Issue
I have a CentOS 7 server with about 20 domains all managed automatically with a vhosts file in /etc/httpd/conf.d.
I am trying to learn Django and wanted to set up a single domain using it, so I added a specific virtualhost to the .conf file.
The result is that the Django domain works fine but all the other sites are broken (try to use Django but cause errors).
The Django domain has two folders: djangodomain.com for static files and djangodomain.app for the Python files.
How can I integrate a single Django domain into my existing many-domain virtual host setup?
Existing vhosts.conf:
<VirtualHost *:80>
serveradmin [email protected]
serveradmin [email protected]
usecanonicalname off
# www.site.com » site.com
rewriteengine on
rewritecond %{HTTP_HOST} ^www\.(.*)$ [nc]
rewriterule ^(.*)$ http://%1 [r=301,l]
# file locations
virtualdocumentroot "/home/username/%0"
<directory "/home/username/*">
allowoverride all
require all granted
options indexes followsymlinks
options +execcgi
options +includes
</directory>
</VirtualHost>
What I added that broke all but the Django site:
<VirtualHost djangodomain.com:80>
ServerName djangodomain.com
ServerAlias www.djangodomain.com
ServerAdmin [email protected]
DocumentRoot /home/username/djangodomain.com
WSGIScriptAlias / /home/username/djangodomain.app/django.wsgi
<Directory /home/username/djangodomain.app>
Order allow,deny
Allow from all
</Directory>
Alias /robots.txt /home/username/djangodomain.com/robots.txt
Alias /favicon.ico /home/username/djangodomain.com/favicon.ico
Alias /images /home/username/djangodomain.com/images
Alias /static /home/username/djangodomain.com/static
ErrorLog /home/username/djangodomain.logs/error.log
CustomLog /home/username/djangodomain.logs/access.log combined
</VirtualHost>
Crossposted to unix.stackexchange.com
Solution
When Apache gets an HTTP request, it needs to know what virtual host is supposed to process this request. Now, the way it works is. Apache picks up the IP address that the client request came into (the server IP, not the client) and it goes through the list of virtual host definitions to find any virtual hosts defined for that IP. If there is more than one, it will look at the Host header and try to match it to a particular ServerName or ServerAlias directive. If it still cannot find one, it will look for a default virtual host.
You have two virtual host definitions. One if the default vhost on port 80 <VirtualHost *:80>
. It is the default because it has * for IP. The other is specific for the IP address <VirtualHost djangodomain.com:80>
. The IP it uses is whatever djangodomain.com resolves to.
So any request that comes to that IP will be handled by the IP specific config before it might be allowed to drop into default.
To fix this, you need to replace your django virtual host directive with <VirtualHost *:80>
, same as your other vhosts. This should put them all at the same parsing priority and it will just use the Host header to figure out the rest.
The said, if you are running a web server with 20+ vhosts, you really need to have better understanding on how it works. Read up on HTTP and web hosting when you have the time.
Answered By - Mad Wombat