Two VirtualHost websites do not work together under Apache 2.4

I'm running Apache 2.4 under Ubuntu 18.04

I'm having this problem where all addresses I type onto the browser bar get redirected to one of the two websites I have configured (in this case, whenever I type an address that should redirect to other-site, I get shown the website under jekyll only.)

For example:

  • typing jekyll on the browser shows me the jekyll website, as expected
  • typing other-site on the browser also shows me the jekyll website, even though there is another VirtualHost listening on that name

I have these two separate sites configured as VHosts under /etc/apache2/sites-available (both of them enabled via a2ensite)

  • jekyll.conf

    <VirtualHost *:80>
          DirectoryIndex index.html
          DocumentRoot /var/www/jekyll/_site
          LimitRequestFieldSize 48000
           <Directory />
                  Options FollowSymLinks
                  AllowOverride None
          </Directory>
          <Directory /var/www/jekyll/_site>
                  AllowOverride All
                  Order allow,deny
                  allow from all
          </Directory>
          <Directory /var/www/jekyll/_site/>
                  Order allow,deny
                  allow from all
          </Directory>
    
          ServerName jekyll
          ServerName http://jekyll
          ServerName http://localhost/jekyll
    
          ServerAdmin webmaster@localhost
    </VirtualHost>
    
  • other-site.conf

    <VirtualHost *:80>
          DirectoryIndex index.html
          DocumentRoot /var/www/other-site/_site
          LimitRequestFieldSize 48000
           <Directory />
                  Options FollowSymLinks
                  AllowOverride None
          </Directory>
          <Directory /var/www/other-site/_site>
                  AllowOverride All
                  Order allow,deny
                  allow from all
          </Directory>
          <Directory /var/www/other-site/_site/>
                  Order allow,deny
                  allow from all
          </Directory>
    
          ServerName other-site
          ServerName http://other-site
          ServerName http://localhost/other-site
    
          ServerAdmin webmaster@localhost
    
    </VirtualHost>
    

I have also added these entries to /etc/hosts so that localhost gets redirected to each site:

127.0.0.1       localhost
127.0.0.1       localhost/jekyll
127.0.0.1       localhost/other-site
127.0.0.1       jekyll
127.0.0.1       other-site
127.0.1.1       felipe-Inspiron-7559

Solution 1:

The ServerName attribute in your Apache configuration files needn't be repeated, as each subsequent line will replace the previous ones.

Instead, you can use ServerName with ServerAlias like this:

ServerName jekyll
ServerAlias jekyll.local *.jekyll *.jekyll.local

Note that this is illogical:

127.0.0.1       localhost/jekyll
127.0.0.1       localhost/other-site

These are not domains (or subdomains), but paths under localhost. As a result, only localhost will be observed. This is why I did not include it in the Apache config as noted above.

So, with this in mind, you can have three Apache configuration files:

000-jekyll.conf

<VirtualHost *:80>
      ServerAdmin webmaster@localhost
      ServerName jekyll
      ServerAlias jekyll.local *.jekyll *.jekyll.local

      DirectoryIndex index.html
      DocumentRoot /var/www/jekyll/_site
      LimitRequestFieldSize 48000

      <Directory /var/www/jekyll/_site>
          Options FollowSymLinks
          AllowOverride All
          Order allow,deny
          Allow from all
      </Directory>

      ErrorLog ${APACHE_LOG_DIR}/jekyll-error.log
      CustomLog ${APACHE_LOG_DIR}/jekyll-access.log combined
</VirtualHost>

001-other.conf

<VirtualHost *:80>
      ServerAdmin webmaster@localhost
      ServerName other-site
      ServerAlias other-site.local *.other-site *.other-site.local

      DirectoryIndex index.html
      DocumentRoot /var/www/other-site/_site
      LimitRequestFieldSize 48000

      <Directory /var/www/other-site/_site>
          Options FollowSymLinks
          AllowOverride All
          Order allow,deny
          Allow from all
      </Directory>

      ErrorLog ${APACHE_LOG_DIR}/other-error.log
      CustomLog ${APACHE_LOG_DIR}/other-access.log combined
</VirtualHost>

999-default.conf

<VirtualHost *:80>
      ServerAdmin webmaster@localhost
      ServerName localhost
      ServerAlias *.localhost * *.*

      DirectoryIndex index.html
      DocumentRoot /var/www
      LimitRequestFieldSize 48000

      <Directory /var/www>
          Options FollowSymLinks
          AllowOverride All
          Order allow,deny
          Allow from all
      </Directory>

      ErrorLog ${APACHE_LOG_DIR}/local-error.log
      CustomLog ${APACHE_LOG_DIR}/local-access.log combined
</VirtualHost>

Apache processes traffic based on the order of the configuration files. So any domain matching the ones specified in 000-jekyll.conf will be handled by that file. If no matches are found, then 001-other.conf will be checked. If no matches are found, then 999-default.conf will be used. Note the ServerAlias in the 999-default.conf file and how it's relying on wide-open wildcards. This means that it will be treated as a catch-all for the traffic that does not match defined config files.

Note: The Apache configuration files were streamlined to eliminate irrelevant Directory blocks and to have each host use their own error logs.