Drafts‎ > ‎

Local websites-testing

posted Apr 24, 2009, 6:22 PM by Brian Hagerty   [ updated May 2, 2009, 2:49 PM ]

Drupal multi-site installation

Various methods, illustrated using local, portable web-server installation

There are two basic types of multisite Drupal installations:
  1. subdomain- (or domain-) based, and
  2. subfolder-based. 
You can also combine these two basic types—that is, within a single multi-site installation, you can use subdomains for some sites, subfolders for others, and subfolders within a subdomain for yet others. 

There are also different ways to make your website appear to be operating out of a location other than where Drupal is actually installed. That is, you might install the Drupal code in one subdirectory but want your Drupal site to appear to operate out of the site's root or out of a subfolder other than the one holding the Drupal code.

This page discusses various types of installations and different methods that I have tested to implement different types of installations. (You can often implement an installation in different ways to the same effect.)

The examples below are based on installing, on a portable local web-server (using XAMPP), the different example sites for which installation profiles are provided in the book Using Drupal by O'Reilly. In every case, the Drupal code is installed two subdirectories below the web-server's main public directory. Specifically:
  • the web server's main public directory is /xampp/htdocs/
  • the Drupal code for these examples is in /xampp/htdocs/usingdrupal/drupal/
  1. Type1: Subdomain-based (appearing to operate out of subdomain root)
    • Method 1: Using Apache VirtualHost directive to map subdomain document root to Drupal installation
      • Site:  Events (Aurora Book Club) at http://events.usingdrupal.local/ 
      • Make this entry in the Apache conf file at: /conf/extra/httpd-vhosts.conf: (the line #events is a comment):
        • #events
          <VirtualHost localhost:80>
              ServerName events.usingdrupal.local
              DocumentRoot "/xampp/htdocs/usingdrupal/drupal"
          </VirtualHost>
        • Note: You will also need to edit httpd-vhosts.conf to enable name-based virtual hosting and ensure that "localhost" works. The following entries do this (but they have nothing to do with the Drupal installation in particular):
          • #Use name-based virtual hosting.
            <VirtualHost localhost:80>
          • #define localhost
            #necessary because turning on NameVirtualHost breaks localhost
            <VirtualHost 127.0.0.1:80>
               ServerName localhost
               DocumentRoot "/xampp/htdocs"
            </VirtualHost>
      • Create subfolder /events.usingdrupal.local/ within your Drupal installation's /sites/ directory; put settings.php in this subfolder (i.e., copy and rename default.settings.php).
        • Browse to http://events.usingdrupal/local/ and complete the Drupal installation script to set the site up.
        • Note: You do not need to add a $base_url value in settings.php.  (By default, it is commented out; you can leave it that way.)  Because of your Apache settings (specifically, the DocumentRoot line in httpd-vhosts.conf), as far as Drupal is concerned, it is operating out of the subdomain's root directory. You only need to set $base_url when Drupal is operating (and know it's operating) out of a subfolder within the subdomain's root directory.
      • You can use Drupal's default .htaccess file wouthout change; it's located in the directory holding the Drupal code (in this installation, /xampp/htdocs/usingdrupal/drupal/). Since requests for the site are directed to the Drupal installation by way of httpd-vhosts.conf, you do not need to rewrite URLs using .htaccess
        • The default .htaccess file includes these lines that enable clean URLs:
          • RewriteCond %{REQUEST_FILENAME} !-f
            RewriteCond %{REQUEST_FILENAME} !-d
            RewriteCond %{REQUEST_URI} !=/favicon.ico
            RewriteRule ^(.*)$ index.php?q=$1 [L,QSA]
        • If you prefer not to use clean URLs, you can comment these lines out and disable clean URLs in your Drupal installation's admin settings.
      • Thoughts:
        • This method is very simple, but it requires access to Apache's configuration files. You probably won't have such access if you use shared hosting (I don't have it at my host, Nearlyfreespeech.net).
        • Also, this method essentially requires you to commit to using the subdomain only for this particular Drupal installation, since the subdomain's document root is mapped to the Drupal-code directory. If you want to use multiple CMSes within the same subdomain, this may not be the best approach. (Then again, it makes a lot of sense to use one CMS for one subdomain, so this is probably a good approach if you can use it.)
    • Method 2: Using .htaccess to redirect subdomain document root to Drupal installation; and using $base_url setting to hide actual installation directory
      • Site: i18n (Migratory Patterns [internationalization features]) at http://i18n.usingdrupal.local/
        • Note: You do not need entries in any Apache configuration files.  But you do need to make sure that your fake subdomain (here, i18n.usingdrupal.local) resolves to your web server (here, localhost). For localhost resolution, you can do this with FoxyProxy.
      • In the .htaccess file in your web server's public document root directory, include these lines, which will direct all requests to this subdomain to the Drupal code directory:
        • RewriteCond %{HTTP_HOST} ^i18n\.usingdrupal\.local$ [NC]
          RewriteRule ^(.*)$ usingdrupal/drupal/$1 [L]
      • Note:  You can use Drupal's default .htaccess file (in the directory holding the Drupal code) without change.
      • Create subfolder /i18n.usingdrupal.local/ within your Drupal installation's /sites/ directory; put settings.php in this subfolder (i.e., copy and rename default.settings.php).
        • Uncomment the $base_url line and edit it to say (the // part is a comment):
          • $base_url = 'http://i18n.usingdrupal.local';  // NO trailing slash!
        • Browse to http://i18n.usingdrupal/local/ and complete the Drupal installation script to set the site up.
      • Thoughts:
        • This method is also simple. It is less efficient than the preceding method because every page request calls mod_rewrite and applies .htaccess rules twice—once at the document root level, and once at the level of the Drupal-code directory.
        • If you use shared hosting, this is the only way to achieve the desired result (Drupal installed in a subdirectory below document root but appearing to be in the subdomain's root directory).
        • You could use .htaccess in document root to redirect requests for specified subdirectories within this subdomain to other directories if you wanted to install multiple CMSes side-by-side.
  2. Type 2: Subfolder-based (appearing to operate out of folder one level below domain or subdomain root)
    • Method 1: Using Apache VirtualHost directive to map domain/subfolder document root to Drupal installation, and using .htaccess to rewrite internal site requests
      • Site: newspaper (Twin City Arts) at http://usingdrupal.local/newspaper/
      • Make this entry in the Apache conf file at: /conf/extra/httpd-vhosts.conf:
        • <VirtualHost localhost:80>
             ServerName usingdrupal.local
             DocumentRoot "/xampp/htdocs"
             Alias /newspaper "/xampp/htdocs/usingdrupal/drupal"
          </VirtualHost>
        • The Alias entry ensures that any request for the site goes directly to the Drupal-code directory and retains the /newspaper/ portion of the URL. That portion is necessary so that Drupal can find the site's settings.php file.
          • (Query: Is this necessary if you have installed Drupal in your web server's public document root directory?)
        • (The DocumentRoot setting won't have any effect for this particular site, since all URIs have /newspaper/ in them.  Also, see discussion above about other entries needed in this file when using Apache's VirtualHost directive.)
      • In the .htaccess file in your Drupal-code directory (here, /usingdrupal/drupal/ within the web server's public document root directory), include these lines:
        • #--- Rules for usingdrupal.local/newspaper/ ---
            RewriteCond %{REQUEST_URI} ^/newspaper/(.*)$
            RewriteCond %{HTTP_HOST} ^usingdrupal\.local$ [NC]
            RewriteCond %{REQUEST_FILENAME} !-f
            RewriteCond %{REQUEST_FILENAME} !-d
            RewriteCond %{REQUEST_URI} !=/favicon.ico
            RewriteRule ^(.*)$ /newspaper/index.php?q=$1 [L,QSA]
          #--- Rules for all other sites ---
            RewriteCond %{REQUEST_URI} !^/newspaper/(.*)$
            RewriteCond %{REQUEST_FILENAME} !-f
            RewriteCond %{REQUEST_FILENAME} !-d
            RewriteCond %{REQUEST_URI} !=/favicon.ico
            RewriteRule ^(.*)$ index.php?q=$1 [L,QSA]
      • Create subfolder /usingdrupal.local.newspaper/ within your Drupal installation's /sites/ directory; put settings.php in this subfolder (i.e., copy and rename default.settings.php).
        • Browse to http://events.usingdrupal/local/ and complete the Drupal installation script to set the site up.
        • Note: You do not need to add a $base_url value in settings.php.  (By default, it is commented out; you can leave it that way.) 
      • Thoughts:
        • This method is not very computationally efficient.
        • This method also requires access to Apache's configuration files, which you aren't likely to have if you use shared hosting. So this solution is not terribly useful.
          • (I'm not entirely sure of this.)
    • Method 2: Using a symbolic link to map domain/subfolder document root to Drupal installation
      • Site: reviews (Super Duper Chefs) at http://usingdrupal.local/reviews/
      • Create a symbolic link in your web server's public document root directory that points from /reviews to the Drupal-code directory.
        • On a Unix system, at a command prompt, use the ln -s command. If Drupal is installed in a /usingdrupal/drupal subdirectory, you could navigate to your web server's public document root directory and enter this command:
          • ln -s ./usingdrupal/drupal ./reviews
          • This means: Create a symbolic link (ln -s) to the subdirectory /usingdrupal/drupal/ from /reviews in this directory (the . character means "this directory").  (You could, of course, do this differently—for instance, by specifying a full pathname and executing the command from some other directory.)
        • On a Windows system, your drive must be NTFS-formatted, and you must use the Junction command. Download Junction from Microsoft and install it, then open a command prompt.  Suppose your web server's public document root directory is N:\xampp\htdocs and Drupal is installed at N:\xampp\htdocs\usingdrupal\drupal. You would enter this command at the prompt:
          • junction n:\xampp\htdocs\reviews n:\xampp\htdocs\usingdrupal\drupal
          • This means: Create a junction (the Windows equivalent to a symbolic link) from /reviews in the web server's document root to the Drupal-code directory.
            • Note that Junction's syntax is the inverse of the Unix ln command's syntax (Junction goes "symlink target_dir"; ln goes "target_dir symlink").  
            • Also, note that Windows junctions aren't entirely portable—they include a drive letter, so if the drive letter of a drive holding a junction changes, the junction will break.  (The junction will work again if you change the drive letter back to what it was when the junction was created.)
            • Finally, note that NTFS drives aren't entirely portable unless you give full permissions to users in the group "Everyone."
              • Most home XP installations use "simple sharing," which does not allow you to directly set all NTFS permissions. This means that if you format an NTFS drive on your home installation, then take it to a computer that uses XP's security features (say, at your work), you may not have full access to the drive.
              • To grant "everyone" (including yourself at work) access to the drive, enable the NTFS security tab on your home machine:
                • In Windows Explorer, seledt: Tools → Folder Options →View tab. 
                • Uncheck "Use simple file sharing (Recommended)"
              • Then right-click the drive, open its Properties sheet, and go to the Security tab.  Give "Everyone" all rights to the drive.
              • For more information, see this Microsoft Knowledgebase article.
      • Create subfolder /usingdrupal.local.reviews/ within your Drupal installation's /sites/ directory; put settings.php in this subfolder (i.e., copy and rename default.settings.php).
        • Browse to http://events.usingdrupal/local/ and complete the Drupal installation script to set the site up.
        • Note: You do not need to add a $base_url value in settings.php.
      • You can use Drupal's default .htaccess file in the Drupal-installation directory (here, /usingdrupal/drupal/ in the web server's public document root, /htdocs/).
      • Thoughts:
        • This is the optimal approach for subfolder-based multisite installation, for two reasons.
          • First, you do not need access to Apache's configuration files.
          • Second, because basic redirection occurs at the file-system level (through the symbolic link), this is computationally much more efficient than using .htaccess for the basic redirection.
        • The only slight downside is a possible limitation on the portability of a local Windows installation—as noted, junction points break if drive letters change.
  3. Type 3: Hybrid of subdomain- and subfolder-based, using symbolic links
    • You may want to install several related Drupal sites in folders within a particular subdomain. For instance:
    • To do this:
      • Ensure that the subdomain (here, usingdrupal.brianhagety.local) resolves to localhost (you can do this with FoxyProxy). You do not need entries in any Apache configuration files. 
      • Create the necessary symbolic links (or junction)
        • From /store in your web server's document root to the Drupal-code directory (here, /usingdrupal/drupal/ in the web server's public document root, /htdocs/).
        • From /wiki in your web server's document root to the Drupal-code directory.
      • Create the required subfolders within your Drupal installation's /sites/ directory and put settings.php in this subfolder. Here, the two folders area:
        • /usingdrupal.brianhagerty.local.store/
        • /usingdrupal.brianhagerty.local.wiki/
      • Browse to each site's root directory and complete the Drupal installation script to set the sites up.
    • Thoughts:
      • This is really just a type of subfolder-based installation.
      • You could do this using .htaccess rules rather than symbolic links, and the installation would be more portable.
      • You need to name the /sites/ subfolders properly. This example illustrates how to do that (subdomain on the left, folder on the right, everything separated by dots).

Links to each installation of Using Drupal sample sites


Sample site
URL  Setup type; location of settings.php
 1. Events (Aurora Book Club) http://events.usingdrupal.local/ • Subdomain using <VirtualHost>
settings.php file in
  /sites/events.usingdrupal.local
/
  2. Gallery (Robinson Family Photo Swap) http://gallery.usingdrupal.local/
• Subdomain using <VirtualHost>
settings.php file in
   /sites/gallery.usingdrupal.local/
 3. i18n (Migratory Patterns [internationalization features]) http://i18n.usingdrupal.local/ • Subdomain using .htaccess and $base_url
settings.php file in
   /sites/i18n.usingdrupal.local/
 4. Jobs (Epic University) http://jobs.usingdrupal.local/ • Subdomain using .htaccess and $base_url
settings.php file in
   /sites/jobs.usingdrupal.local/
 5. Newspaper (Twin City Arts)
http://usingdrupal.local/newspaper/ • Subfolder using <VirtualHost> Alias  and .htaccess
settings.php file in
   /sites/usingdrupal.local.newspaper/
 6. Reviews (Super Duper Chefs)
http://usingdrupal.local/reviews/ • Subfolder using Junction (symbolic link)
settings.php file in
   /sites/usingdrupal.local.reviews/
 7. Store (Sweet Tees)
http://usingdrupal.brianhagerty.local/store/ • Hybrid: subfolder in a subdomain
• Using Junction (symbolic link)
settings.php file in
   /usingdrupal.brianhagerty.local.store/
 8. Wiki (Berchem University SGA)
http://usingdrupal.brianhagerty.local/wiki/ • Hybrid: subfolder in a subdomain
• Using Junction (symbolic link)
settings.php file in
   /sites/usingdrupal.local.wiki/

Comments