How to Do Multiple Processes for Django, on My Wsgi Apache

How do I do multiple processes for Django, on my WSGI apache?

Use the WSGIDaemonProcess directive to put the app in daemon mode and specify the number of daemon processes and threads.

Deploying multiple django apps on Apache with mod_wsgi

This is a problem with the wsgi.py file generated by Django 1.4. It will not work where trying to host two distinct Django instances in the same process, even though in separate sub interpreters.

Change:

os.environ.setdefault("DJANGO_SETTINGS_MODULE", "site1.settings")

to:

os.environ["DJANGO_SETTINGS_MODULE"] = "site1.settings"

Or better still use daemon mode and delegate each to run in distinct daemon process groups.

That is, instead of:

WSGIScriptAlias /site1 /var/www/py/site1/site1/wsgi.py
WSGIScriptAlias /site2 /var/www/py/site2/site2/wsgi.py

WSGIPythonPath /var/www/py/site1:/var/www/py/site2

use:

WSGIDaemonProcess site1 python-path=/var/www/py/site1
WSGIScriptAlias /site1 /var/www/py/site1/site1/wsgi.py process-group=site1 application-group=%{GLOBAL}

WSGIDaemonProcess site2 python-path=/var/www/py/site2
WSGIScriptAlias /site2 /var/www/py/site1/site2/wsgi.py process-group=site2 application-group=%{GLOBAL}

UPDATE

Note that there is a whole blog post about this and other causes now.

  • http://blog.dscpl.com.au/2012/10/requests-running-in-wrong-django.html

multiple django sites with apache & mod_wsgi

Your ServerName/ServerAlias directives are wrong. ServerName should be hostname. You probably should just delete ServerAlias.

Then just do the obvious and duplicate VirtualHost/Listen directives, just changing the port number and locations of scripts in the file system.

Finally, do not set DocumentRoot to be where your Django code is as it makes it easier to accidentally expose your source code to download if you stuff up Apache configuration. So, just remove DocumentRoot directive from VirtualHost for Django sites.

Listen 80

<VirtualHost *:80>
ServerName www.example.com
WSGIScriptAlias / /opt/django/site1/apache/django.wsgi
Alias /media /opt/django/site1/media/statics
Alias /admin_media /home/myuser/Django-1.1/django/contrib/admin/media

<Directory opt/django/site1/apache>
Order allow,deny
Allow from all
</Directory>

<Directory /home/myuser/Django-1.1/django/contrib/admin/media>
Order allow,deny
Allow from all
</Directory>
</VirtualHost>

Listen 8080

<VirtualHost *:8080>
ServerName www.example.com
WSGIScriptAlias / /opt/django/site2/apache/django.wsgi
Alias /media /opt/django/site2/media/statics
Alias /admin_media /home/myuser/Django-1.1/django/contrib/admin/media

<Directory opt/django/site2/apache>
Order allow,deny
Allow from all
</Directory>

<Directory /home/myuser/Django-1.1/django/contrib/admin/media>
Order allow,deny
Allow from all
</Directory>
</VirtualHost>

Listen 8090

<VirtualHost *:8090>
ServerName www.example.com
WSGIScriptAlias / /opt/django/site3/apache/django.wsgi
Alias /media /opt/django/site3/media/statics
Alias /admin_media /home/myuser/Django-1.1/django/contrib/admin/media

<Directory opt/django/site3/apache>
Order allow,deny
Allow from all
</Directory>

<Directory /home/myuser/Django-1.1/django/contrib/admin/media>
Order allow,deny
Allow from all
</Directory>
</VirtualHost>

I have also add missing Directory directive for allowing access to static files. You should review paths however.

Make sure you read:

http://code.google.com/p/modwsgi/wiki/IntegrationWithDjango
http://code.google.com/p/modwsgi/wiki/ConfigurationGuidelines#Hosting_Of_Static_Files

for further information.


UPDATE 1

BTW, since you are using PHP in same Apache, you would be much better off using mod_wsgi daemon mode and push each Django instance out into its own separate process. That allows those processes to be multithreaded, even though main Apache processes are forced to be single threaded because of PHP. End result will be much much less memory being used than if running multiple Django instances in each process under embedded mode with prefork MPM. Your Django code just needs to be thread safe. Configuration in addition to above would be to add WSGIDaemonProcess/WSGIProcessGroup to each Django VirtualHost, where name of daemon process group is different for each VirtualHost.

<VirtualHost *:80>
WSGIDaemonProcess site1 display-name=%{GROUP}
WSGIProcessGroup site1
... existing stuff
</VirtualHost>

<VirtualHost *:8080>
WSGIDaemonProcess site2 display-name=%{GROUP}
WSGIProcessGroup site2
... existing stuff
</VirtualHost>

<VirtualHost *:8090>
WSGIDaemonProcess site3 display-name=%{GROUP}
WSGIProcessGroup site3
... existing stuff
</VirtualHost>

This also allows you to more easily restart each Django instance without restart whole of Apache. Read:

http://code.google.com/p/modwsgi/wiki/QuickConfigurationGuide#Delegation_To_Daemon_Process
http://code.google.com/p/modwsgi/wiki/ReloadingSourceCode

multiple django apps on a apache vhost where one is on root with mod_wsgi

Wrong order. Use:

WSGIScriptAlias /app2 <path to django wsgi file for app2>
WSGIScriptAlias / <path to django wsgi file for app1>

The most deeply nested must be first, else '/' will be matched first and override everything else.


UPDATE 1

After additions to question. Now use:

<VirtualHost <server ip>:80>
ServerName site1.com

##### app2 CONFIG
WSGIDaemonProcess app2 python-path=/<path to django app2>/:/<path to virtualenv app2>/ threads=15 display-name=%{GROUP}

<Location /app2>
WSGIProcessGroup app2
</Location>

WSGIScriptAlias /app2 /<path to app2 wsgi file>/

##### app1 CONFIG
WSGIDaemonProcess app1 python-path=/<path to django app1>/:/<path to virtualenv app1>/ threads=15 display-name=%{GROUP}

WSGIProcessGroup app1

WSGIScriptAlias / /<path to app1 wsgi file>
</VirtualHost>

You need to scope the WSGIProcessGroup directive to the sub URL so only that sub URL's requests are delegated to the mod_wsgi daemon process group.

Another way of writing above is:

<VirtualHost <server ip>:80>
ServerName site1.com

##### app2 CONFIG
WSGIDaemonProcess app2 python-path=/<path to django app2>/:/<path to virtualenv app2>/ threads=15 display-name=%{GROUP}

WSGIScriptAlias /app2 /<path to app2 wsgi file>/ process-group=app2

##### app1 CONFIG
WSGIDaemonProcess app1 python-path=/<path to django app1>/:/<path to virtualenv app1>/ threads=15 display-name=%{GROUP}

WSGIScriptAlias / /<path to app1 wsgi file> process-group=app1
</VirtualHost>

In other words, use the process-group option to WSGIScriptAlias to indicate where each should run.

When using daemon mode and only one application per process, also recommended to add:

WSGIApplicationGroup %{GLOBAL}

This forces use of main Python interpreter context by WSGI application in respective processes, avoiding problems that can arise where some Python packages with C extensions are not implemented correctly so as to work with Python sub interpreters.

Howto configure Apache WSGI for multiple separate Django instances?

The other answers mention setting the python path, however using WSGIPythonPath or WSGIPythonHome are not correct. The WSGIPythonPath / WSGIPythonHome can only be set server-wide, so no different paths per virtualhost.

You would want to use the WSGIDaemonProcess python-path and home arguments to set the python path and your apps home directory per virtualhost.

Also, within your code there is no need to adjust python paths; just make sure your virtualhost config is correct.

apache creates more then one process

Apache runs a parent process and then one child worker process with that configuration. The parent process would be quite small in size as all it is doing is managing the child worker process and restarts it if it dies etc. Requests are only handled by the child worker process. So what you are seeing is normal.

Why are you trying to restrict it to one process? If it is to satisfy some requirement of your WSGI application that can only have one process, you should not be using embedded mode anyway. Use daemon mode of mod_wsgi, in which case the WSGI application will use one process by default.

So put back the Apache MPM settings and then use:

WSGIRestrictEmbedded On

WSGIDaemonProcess myapp
WSGIScriptAlias / /some/path/myapp.wsgi process-group=myapp application-group=%{GLOBAL}

This will result in the Apache parent process, however many child worker process Apache needs to accept and proxy requests, and the single mod_wsgi daemon process running the WSGI application, to which the child worker processes are proxying requests.



Related Topics



Leave a reply



Submit