Setting up multi web site developer testbeds/sandboxes on localhost

Scenario

——————————————————————
You are maintaining several web-sites (site1.com, site2.org, etc…). Having just one web-site at localhost with all files (DocumentRoot) at /var/www/html is not an option for you. You need to be able to test all of them and to access them in a convenient way.
apache-vHosts

Solution

Setup apache with Virtual Hosts, give your sites some local names in /etc/hosts and access them like that. This solution should work for drupal sites, wordpress sites, plain html or just about any other CMS site or plain php site.


1. Local names in /etc/hosts

Give local names to your websites in the hosts file. For example, if your real websites are site1.com and site2.com name them site1.local and site2.local.
Add entries for them in /etc/hosts:

127.0.0.1 localhost.localdomain localhost site1.local site2.local

2. Create your sites’ directories on you local disk

… usually in /var/www/html, i.e.

  • /var/www/html/local.site1
  • /var/www/html/local.site2

Copy all site1 files to /var/www/local.site1 and repeat process for all other sites on.


3. Setup VirtualHosts

Enable apache’s VirtualHosts and tell apache how to serve them.

3.1 On Apache 2.2 and earlier

Edit /etc/httpd/conf/httpd.conf:

<Directory "/var/www/html">
    # this will enable local, per-site .htaccess files 
    # instead of one global one for the entire system
    AllowOverride All
</Directory>
<VirtualHost *:80>
    DocumentRoot "/var/www/html"
</VirtualHost>

# site1 domain
<VirtualHost *:80>
    ServerName site1.local
    DocumentRoot "/var/www/html/local.site1"
    <Directory "/var/www/html/local.site1">
        allow from all
        order allow,deny
        # Enables .htaccess files for this site
       AllowOverride All
    </Directory>
</VirtualHost>

# site2 domain
<VirtualHost *:80>
    ServerName site2.local
    DocumentRoot "/var/www/html/local.site2"
    <Directory "/var/www/html/local.site2">
        allow from all
        order allow,deny
        # Enables .htaccess files for this site
        AllowOverride All
    </Directory>
</VirtualHost>

3.1 On Apache 2.3 – no idea…

 

3.2 On Apache 2.4.29 and newer

3.2.1. VERY IMPORTANT: enable mod_ssl!
# sudo a2enmod ssl

3.2.2 – Create the dirs for your virtual sites

# sudo mkdir -p /var/www/html/site1.local
# sudo mkdir -p /var/www/html/site2.local
# sudo chown -R $USER:$USER /var/www/html/site1.local
# sudo chown -R $USER:$USER /var/www/html/site2.local

-OR-

create a symlink ‘html’ in /var/www and setup your actual tree elsewhere.

3.2.3 – Create some test html files for the virtual hosts:

<html>
  <head>
    <title>Test Site 1</title>
  </head>
  <body>
    <h1>Local Test Site 1</h1>
    <p>This is a local Test Site (1). Purpose - to test Virtual Hosts setup.</p>
  </body>
</html>

3.2.4 – Apache comes with a default virtual host file called 000-default.conf that we can use as a base.

# sudo cp /etc/apache2/sites-available/000-default.conf /etc/apache2/sites-available/test1.local.conf
# sudo cp /etc/apache2/sites-available/000-default.conf /etc/apache2/sites-available/test2.local.conf

Edit the files and modify the following entries:

ServerName test1.local
ServerAlias www.test1.local
ServerAdmin webmaster@test1.local
DocumentRoot /var/www/html/local.test1

<Directory /var/www/html/local.test1>
    ...
</Directory>

2.5 – Enable your virtual host sites:

# sudo a2ensite test1.local.conf
# sudo a2ensite test2.local.conf

3.3 On Apache 2.4 (older versions)

A. VERY IMPORTANT! Fix Directory sections of main httpd conf file
(/etc/httpd/conf/httpd.conf):

<Directory />
 # protect main dir
 AllowOverride none
 Require all granted
</Directory>

<Directory "/var/www/html">
    # enable local, per-site .htaccess files instead of
    # one global one for the entire system
    AllowOverride All
</Directory>

 

B. Create file /etc/httpd/conf.d/httpd-vhosts.conf:

<VirtualHost *:80>
# entry for the main directory (localhost)
    ServerAdmin webmaster@localhost
    DocumentRoot "/var/www/html"
    ServerName localhost
</VirtualHost>

<VirtualHost *:80>
    ServerAdmin webmaster@site1.local
 DocumentRoot "/var/www/html/local.site1"
 ServerName site1.local
 ServerAlias www.site1.local
 ErrorLog "/var/log/httpd/site1.local-error_log"
 CustomLog "/var/log/httpd/site1.local-access_log" common
</VirtualHost>

4. Adjust site’s config data

If necessary edit local settings/files for each site to reflect specific rules. Depending on what framework you use these may be records in the site’s database (e.g. siteurl in wp_options table for WordPress) or config files in the DocumentRoot tree for each site (e.g. .htaccess or wp-config.php).

— For opencart:

Inside opencart’s target directory, add a .htaccess file (or rename the htaccess.txt which is usually found there by default) and in it append the following lines to the end of the file:

RewriteCond %{HTTP_HOST} ^([a-z.]+)?fit1\.bg$ [NC]
RewriteCond %{HTTP_HOST} !^www\. [NC]
RewriteRule .? http://www.%1fit1.bg%{REQUEST_URI} [R=301,L]

— For WP:

 - DB::wp_options::siteurl  --> adjust field to reflect the site's URL
 - DB::wp_options::home   --> same as above
 - .htaccess
 # BEGIN WordPress
 <IfModule mod_rewrite.c>
    RewriteEngine On
    RewriteBase /
    RewriteRule ^index\.php$ - [L]
    RewriteCond %{REQUEST_FILENAME} !-f
    RewriteCond %{REQUEST_FILENAME} !-d
    RewriteRule . /index.php [L]
 </IfModule>
 # END WordPress

— For drupal, and particularly for drupal’s “Clean URL’s” feature:

By default all pages of a drupal site start with /?q= e.g. http://www.mysite.com/?q=admin/config/search/clean-urls. This obviously is difficult to remember and type, it looks kinda ugly and also search engines don’t like it. So drupal provides a special feature called “Clean URLs”, and if enabled it will transform the above link into http://www.mysite.com/admin/config/search/clean-urls – which obviously looks a lot nicer.

To enable it we need mod_rewrite (test it with phpinfo()) and some voodoo in /etc/httpd/conf/httpd.conf or in the local .htaccess file. By local I mean the per-site .htaccess files (which live in the local.site1 and local.site2 dirs in the examples above), as opposed to the global .htaccess file in /var/www/html.

The ‘voodoo’ (the red stuff) looks like this:

… in the httpd.conf file:

<VirtualHost *:80>
  ServerName site1.local
  DocumentRoot "/var/www/html/local.site1"
  <Directory "/var/www/html/local.site1">
    allow from all
    order allow,deny
    # Enables .htaccess files for this site
    AllowOverride All
    # Enables drupal "clean URLs"
    RewriteEngine on
    RewriteBase /
    RewriteCond %{REQUEST_FILENAME} !-f
    RewriteCond %{REQUEST_FILENAME} !-d
    RewriteRule ^(.*)$ index.php?q=$1 [L,QSA] 
  </Directory>
</VirtualHost>

… in the .htaccess file inside drupal’s directory:

# Various rewrite rules.
<IfModule mod_rewrite.c>
  RewriteEngine on
  ...
  # If your site is running in a VirtualDocumentRoot at http://example.com/,
  # uncomment the following line:
  RewriteBase /
  ...
  # Pass all requests not referring directly to files in the filesystem to
  # index.php. Clean URLs are handled in drupal_environment_initialize().
  RewriteCond %{REQUEST_FILENAME} !-f
  RewriteCond %{REQUEST_FILENAME} !-d
  RewriteCond %{REQUEST_URI} !=/favicon.ico
  RewriteRule ^ index.php [L]
  ...
</IfModule>

Even though on a localhost testing machine where you usually have root access you can easily put this in httpd.conf, the better approach is to put it into the .htaccess file.

Why? Because when you eventually go live it will be transferred to your live site automatically. Put it in httpd.conf and you have to remember to edit your .htaccess file on your live server when you go live (which usually happens after 1-2 weeks of testing and by that time you have happily forgotten that your httpd conf file was edited and then the clean URLs on your live server don’t work and it drives crazy trying to figure out why it works locally but not no the live server, etc. etc…
So… save yourself the trouble and put it inside the site’s .htaccess file :))

——————————————————————

5. Edit main .htaccess file

This is usually not necessary, but if you see weird 404 errors, particularly if your front page works but all the other pages of your site do not – you may need this:

List all your sites in the /var/www/html/.htaccess file, like this:

 RewriteCond %{HTTP_HOST} ^(www.)?site1.local$
 RewriteCond %{REQUEST_URI} !^/local.site1/
 # Don't change the following two lines (REQUEST_FILENAME).
 RewriteCond %{REQUEST_FILENAME} !-f
 RewriteCond %{REQUEST_FILENAME} !-d
 RewriteRule ^(.*)$ /local.site1/$1
 RewriteCond %{HTTP_HOST} ^(www.)?site1.local$
 RewriteRule ^(/)?$ local.site1/index.php [L]

Use the above as template for all your other web sites.

——————————————————————

6. Use relative URL’s.

When developing the sites avoid using absolute URLs as much as possible – reference links/paths/images like this: “/images/logo1.jpg” rather than “http://site1/images/logo1.jpg”. This way you will not need to go through all these data and change http://site1 to http://site1.com when uploading to your live server.

——————————————————————

Leave a Reply

Your email address will not be published. Required fields are marked *