Django multiple sites with apache mod_wsgi: Request going to wrong site - django

I am trying to run 2 Django sites from one apache server using virtual hosts with mod_wsgi. The problem is that all my request are going to the same Django site(probably the first one loaded by Apache) even when I use the hostname for the other site. My sites are
https://staging-test.mydomain.com
and
https://staging.mydomain.com
Here is the content of my virtual hosts files. I have created the two files for deployment which I place in the site-enabled directory of my Apache installation(Ubuntu). Two files because it helps in dev-ops. Regardless, the config looks like
<VirtualHost _default_:443>
ServerAdmin webmaster#localhost
ServerName https://staging-test.mydomain.com
SetEnv PYTHON_EGG_CACHE /tmp
WSGIDaemonProcess https://staging-test.mydomain.com user=www-data group=www-data processes=10 threads=1 python-path=/home/talha/site1 display-name=wsgid
WSGIProcessGroup https://staging-test.mydomain.com
WSGIScriptAlias / /home/talha/site1/wsgi.py process-group=https://staging-test.mydomain.com application-group=%{RESOURCE}
WSGIPassAuthorization On
WSGIApplicationGroup %{RESOURCE}
</VirtualHost>
<VirtualHost _default_:443>
ServerAdmin webmaster#localhost
ServerName https://staging.mydomain.com
SetEnv PYTHON_EGG_CACHE /tmp
WSGIDaemonProcess https://staging.mydomain.com user=www-data group=www-data processes=10 threads=1 python-path=/home/talha/site2 display-name=wsgid
WSGIProcessGroup https://staging.mydomain.com
WSGIScriptAlias / /home/talha/site2/wsgi.py process-group=https://staging.mydomain.com application-group=%{RESOURCE}
WSGIPassAuthorization On
WSGIApplicationGroup %{RESOURCE}
</VirtualHost>
I have tried to use the WSGIDaemonProcess and WSGIProcessGroup to make the sites run in different processes, however the requests are still going to only one of them.
Any ideas what might be wrong here?

As someone pointed out, your initial problem is that you should not use a URI in the ServerName, it must be just the host name. Beyond fixing that, then make sure you read:
http://blog.dscpl.com.au/2012/10/requests-running-in-wrong-django.html
You are hitting a variation of the default VirtualHost problem described in that post due to wrong setting for ServerName.

Related

Apache, mod-wsgi: Any URL is served by project, ServerName is ignored

I am setting up a Django project and Apache on Ubuntu 20. The below setup correctly displays the Django project, however ANY URL that points to the server's IP address is served this project. I obviously need to limit this to my particular website mysite.com. ServerName is ignored.
I have looked at other question/answers. However, they usually mention httpd.conf, which is no longer used in Apache. Or, there is no accepted answer. Or, it just isn't relevant to my setup. Also, I've been told not to touch apache2.conf. This is a brand-new installation instance so no weird stuff hanging around.
I will eventually need to have multiple sites served on the same server.
Install Apache mod-wsgi:
sudo apt install apache2 apache2-utils ssl-cert libapache2-mod-wsgi
sudo a2enmod rewrite
sudo systemctl restart apache2
Set up .conf file and activate it:
Copy mysite.com.conf to /etc/apache2/sites-available
sudo a2ensite mysite.com.conf
sudo a2dissite 000-default.conf
sudo systemctl reload apache2
sudo systemctl restart apache2
mysite.com.conf:
<VirtualHost *:80>
WSGIApplicationGroup %{GLOBAL}
WSGIDaemonProcess test_project_ns processes=1 threads=10 python-path=/home/ubuntu/test_project python-home=/home/ubuntu/test_project/test_env
WSGIProcessGroup test_project_ns
ServerAdmin webmaster#localhost
DocumentRoot /var/www/html
ServerName mysite.com
ServerAlias www.mysite.com
ErrorLog ${APACHE_LOG_DIR}/error.log
CustomLog ${APACHE_LOG_DIR}/access.log combined
<Directory /home/ubuntu/test_project/test_ui>
<Files wsgi.py>
Require all granted
</Files>
</Directory>
WSGIScriptAlias / /home/ubuntu/test_project/test_ui/wsgi.py
</VirtualHost>
Result:
mysite.com correctly serves up the Django project, but so does ANY other website that points to the server.
Output of apache2ctl -S:
VirtualHost configuration:
*:80 mysite.com (/etc/apache2/sites-enabled/mysite.com.conf:1)
ServerRoot: "/etc/apache2"
Main DocumentRoot: "/var/www/html"
Main ErrorLog: "/var/log/apache2/error.log"
Mutex watchdog-callback: using_defaults
Mutex rewrite-map: using_defaults
Mutex default: dir="/var/run/apache2/" mechanism=default
PidFile: "/var/run/apache2/apache2.pid"
Define: DUMP_VHOSTS
Define: DUMP_RUN_CFG
User: name="www-data" id=33 not_used
Group: name="www-data" id=33 not_used
So if apache doesn't find a match for the URL, it uses the first virtual host, regardless of ServerName. I therefore added a blocking virtual host before the real one. Now all sites that don't match ServerName or ServerAlias are shown a standard forbidden message.
This also works with multiple site.com.conf files. I add the blocking virtual host to the top of each file so I don't have to worry about which virtual host is "first" when there are multiple files.
<VirtualHost *:80>
<Location />
Deny from all
</Location>
</VirtualHost>
<VirtualHost *:80>
ServerName mysite.com
.....
</VirtualHost>

Routing http request to WSGI app (Flask + Apache)

My Flask based web app is ready to go, and I'm currently connecting it up to Apache 2.2.
When I start Apache serving the app from root
WSGIScriptAlias / /var/www/path/to/script.wsgi
everything works as expected. However, I want to serve multiple versions of the WSGI script that will connect to different databases, which means I need to serve each with a unique alias:
WSGIScriptAlias /firstscript /var/www/path/to/first/script.wsgi
...
WSGIScriptAlias /secondscript /var/www/path/to/second/script.wsgi
When I try to access one of these:
www.example.com/firstscript
the WSGI app loads, but all http requests are still routed to the root. What is the best way for me to reroute all http requests to my WSGI app? Here is my apache config:
WSGIPythonHome /usr
WSGIPythonPath /var/www/path/to/first
<VirtualHost *>
WSGIDaemonProcess firstscript user=apache group=apache threads=5 python-path=/lib/python2.7/site-packages
WSGIScriptAlias /firstscript /var/www/path/to/first/script.wsgi
<Directory /var/www/path/to/first>
WSGIProcessGroup %{GLOBAL}
WSGIApplicationGroup %{GLOBAL}
Order deny,allow
Allow from all
</Directory>
</VirtualHost>
EDIT:
I've followed the (much appreciated) recommendations from #grahamdumpleton, which have helped me to clean up my Apache configs, but my http requests continue to be routed to the Apache server's root, rather than the WSGI app. Here's my current config:
WSGIPythonHome /usr
WSGIPythonPath /var/www/path/to/first
<VirtualHost *>
WSGIDaemonProcess firstscript threads=5
WSGIScriptAlias /firstscript /var/www/path/to/first/script.wsgi process-group=firstscript application-group=%{GLOBAL}
<Directory /var/www/path/to/first>
WSGIApplicationGroup %{GLOBAL}
Order deny,allow
Allow from all
</Directory>
</VirtualHost>
I've also tried adding a process group under the directory tag: WSGIProcessGroup firstscript, which also failed to have any impact.
The following should be removed for a start:
WSGIProcessGroup %{GLOBAL}
This is causing everything to be handled in the same Python interpreter, and not even in the daemon process group, so likely they are interfering with each other.
Using:
python-path=/lib/python2.7/site-packages
is also wrong. You don't need that when using system Python, and python-path is wrong way of referring to a virtual environment anyway.
Finally you don't need:
user=apache group=apache
either as defaults to using the Apache user already.
That first change may be enough to get it working as each application will now run in a separate sub interpreter of the daemon process group.
If that doesn't work, you should create more than one daemon process group and delegate each to a separate daemon process group.
That would be done using:
WSGIDaemonProcess firstscript threads=5
WSGIScriptAlias /firstscript /var/www/path/to/first/script.wsgi process-group=firstscript application-group=%{GLOBAL}
WSGIDaemonProcess secondscript threads=5
WSGIScriptAlias /secondscript /var/www/path/to/second/script.wsgi process-group=secondscript application-group=%{GLOBAL}

how can I deploy multiple django cms projects under same domain.I am using apache 2.2 and mod_wsgi

I need to deploy two Django Cms projects under the same domain name. I need to retrieve the two sites when calling the following domain.
http://rndbkw.tk
http://rndbkw.tk/blog
I have two wsgi configurations included in the httpd.conf
for http://rndbkw.tk
ServerName rndbkw.tk
WSGIDaemonProcess rnd python-path=/home/rndbkw/djangocms:/home/rndbkw/virtualenv2.7/lib/python2.7/site-packages/
WSGIProcessGroup rnd
WSGIScriptAlias / /home/rndbkw/djangocms/rnd/wsgi.py
ServerName rndbkw.tk
WSGIDaemonProcess blog python-path=/home/rndbkw/projects/djangocms:/home/rndbkw/projects/virtualenv2.7/lib/python2.7/site-packages/
WSGIProcessGroup blog
WSGIScriptAlias / /home/rndbkw/projects/djangocms/rnd/wsgi.py
But i cannot get back http://rndbkw.tk/blog
You have a few problems with your configuration of:
ServerName rndbkw.tk
WSGIDaemonProcess rnd python-path=/home/rndbkw/djangocms:/home/rndbkw/virtualenv2.7/lib/python2.7/site-packages/
WSGIProcessGroup rnd
WSGIScriptAlias / /home/rndbkw/djangocms/rnd/wsgi.py
ServerName rndbkw.tk
WSGIDaemonProcess blog python-path=/home/rndbkw/projects/djangocms:/home/rndbkw/projects/virtualenv2.7/lib/python2.7/site-packages/
WSGIProcessGroup blog
WSGIScriptAlias / /home/rndbkw/projects/djangocms/rnd/wsgi.py
Instead use:
ServerName rndbkw.tk
WSGIDaemonProcess blog python-home=/home/rndbkw/projects/virtualenv2.7 python-path=/home/rndbkw/projects/djangocms
WSGIScriptAlias /blog /home/rndbkw/projects/djangocms/rnd/wsgi.py process-group=blog application-group=%{GLOBAL}
WSGIDaemonProcess rnd python-home=/home/rndbkw/virtualenv2.7 python-path=/home/rndbkw/djangocms
WSGIScriptAlias / /home/rndbkw/djangocms/rnd/wsgi.py process-group=rnd application-group=%{GLOBAL}
Changes made were:
Mount blog at sub URL of /blog.
Move the WSGIScriptAlias for /blog before that for / so that it takes precedence, else that for / will always match first and nothing will ever get through the the blog site.
Per best practice, use python-home of WSGIDaemonProcess directive to specify the location of the virtual environment instead of adding site-packages using python-path.
Use process-group option to WSGIScriptAlias to indicate which daemon process group to use. This makes it more precise. Your use of WSGIProcessGroup wouldn't have worked as wasn't qualified to a Location or Directory scope so whichever of the two WSGIProcessGroup directives was last would have overridden the first.
Set application-groupto %{GLOBAL} to force use of main interpreter context of each daemon process. This solves problems with some third party extension modules for Python that will not work in sub interpreter contexts.
The last line in your configuration needs to be
WSGIScriptAlias /blog /home/rndbkw/projects/djangocms/rnd/wsgi.py

How to put Django within a subdirectory of a website?

I want to run WordPress at mysite.com/, because it's easier to edit sales copy and such. I want to run my Django site within mysite.com/members/
httpd.conf:
<VirtualHost *:80>
ServerName mysite.com
ServerAlias www.mysite.com
DocumentRoot /var/www/mysite.com
WSGIDaemonProcess mysite python-path=/var/www/mysite.com/mysite:/var/www/mysite.com/
WSGIProcessGroup mysite
WSGIScriptAlias / /var/www/mysite.com/mysite/mysite/wsgi.py
</VirtualHost>
What exactly do I need to do so that Django runs within the /members/ directory on my domain/website?
Use:
WSGIScriptAlias /members /var/www/mysite.com/mysite/mysite/wsgi.py
Do be aware that by doing that, since you have made the mistake of setting DocumentRoot to be a parent directory of your source code, people will be able to download the source code, including sensitive information in the settings module.
So, do not set DocumentRoot to be what you have. Have it refer to an en empty directory, of the default htdocs directory for the whole server.
To follow up on the previous answer and comments, here's an example of how I might do this if I had to:
<VirtualHost *:80>
# WordPress
ServerName mysite.com
ServerAlias www.mysite.com
DocumentRoot /var/www/mysite.com
# Django
WSGIDaemonProcess mysite python-path=/var/django/django_project/virtualenv/django_project
WSGIProcessGroup mysite
WSGIScriptAlias /members /var/django/django_project/django_project/wsgi.py
Alias /members/static/ /var/django/django_project/static/
</VirtualHost>
Definitely understand the security concerns raised in comments, however.

Multiple Django applications using virtualenv on Apache 2 on Ubuntu 11

I've successfully setup one Django application using virtualenv on Ubuntu and Apache 2, using the WSGIPythonHome directive pointing to my virtualenv location. Now I am in need to create a separate Django application, that is going to run on Apache on a different port on the same Ubuntu server. I am wondering if there's a way to have Apache run multiple WSGIPythonHome instances? Currently with WSGIPythonHome being set to one virtualenv root, there's a problem with imports on the second Django app…
The best way to do this, I've discovered about a year ago, is to use WSGI as a daemon and set the python path in the daemon directive. Example is below
<VirtualHost *:80>
ServerName yourhost.com
<Directory />
Order deny,allow
#Require all granted
</Directory>
#Alias /static /opt/yourhost/static
WSGIScriptAlias / /opt/yourhost/wsgi.py
WSGIApplicationGroup %{GLOBAL}
WSGIDaemonProcess yourhost.com python-path=/opt/yourhost:/opt/yourhost/venv/lib/python2.7/site-packages processes=2 threads=15 display-name=%{GROUP}
WSGIProcessGroup yourhost.com
</VirtualHost>
WSGISocketPrefix /var/run/wsgi
You should do this with separate virtual hosts in Apache. Each one can listen to a particular port, and can have its own separate WSGI directives.