Deploy Django with WSGI
Django's primary deployment platform is WSGI, which is the standard Python interface for web servers and applications. The startproject command sets up a minimal default WSGI configuration for you that you can tweak as needed.
The application Object
The key concept of deploying with WSGI is the application callable. Web servers use this callable to communicate with your code. When you start a project, Django creates a wsgi.py file containing this exact object.
WSGI servers obtain the path to this callable from their configuration. Django's built-in development server (runserver) finds it by reading the WSGI_APPLICATION setting. By default, this is set to <project_name>.wsgi.application.
Configuring the Settings Module
When a WSGI server loads your application, Django needs to import the settings module to know how your application is defined. Django uses the DJANGO_SETTINGS_MODULE environment variable to locate this file.
If this variable is not set, the default wsgi.py file automatically sets it to mysite.settings (where mysite is your project name).
NOTE
Environment variables are process-wide. If you run multiple Django sites in the same process (which often happens with Apache and mod_wsgi), this default behavior will fail. To avoid this, use daemon mode with each site in its own process, or enforce the setting directly in your wsgi.py file using os.environ["DJANGO_SETTINGS_MODULE"] = "mysite.settings".
Applying WSGI Middleware
You can apply custom WSGI middleware by wrapping the application object directly in your wsgi.py file. You can also replace the Django WSGI application with a custom WSGI application that delegates to Django later.
from helloworld.wsgi import HelloWorldApplication
# Wrap the default Django application
application = HelloWorldApplication(application)Deploying with Gunicorn
Gunicorn ('Green Unicorn') is a pure-Python WSGI server for UNIX. It has no dependencies and can be installed using pip:
python -m pip install gunicornOnce installed, you can start the server by pointing it to your WSGI application. You execute the gunicorn command and pass the module path to your application object. For a project named mysite, you would run:
gunicorn mysite.wsgiBy default, this command starts a process running on your local machine, listening on 127.0.0.1:8000. In a production environment, you typically bind Gunicorn to a specific IP address and port and you run it behind a reverse proxy web server like Nginx. Refer to this page for more details.
Deploying with uWSGI
uWSGI is another fast, self-healing and highly configurable WSGI server coded in pure C. It is widely used for heavy-duty deployments.
You can install it by running:
# Install current stable version
python -m pip install uwsgi
# Or install LTS (long term support) version
python -m pip install https://projects.unbit.it/downloads/uwsgi-lts.tar.gzTo run your Django project, you must tell uWSGI to use the HTTP protocol, specify a port and point it to your WSGI module. For example, the following command will serve your project on port 8000:
uwsgi --http :8000 --module mysite.wsgi:applicationSimilar to Gunicorn, uWSGI is usually deployed behind a reverse proxy rather than facing the public internet directly.
Deploying with Apache and mod_wsgi
Deploying Django with Apache and mod_wsgi is a tried and tested way to get Django into production. mod_wsgi is an Apache module which can host any Python WSGI application, including Django. Django will work with any version of Apache which supports mod_wsgi.
Once you’ve got mod_wsgi installed and activated, edit your Apache server’s httpd.conf file and add the following lines, to route requests to your Django project:
WSGIScriptAlias / /path/to/mysite.com/mysite/wsgi.py
WSGIPythonHome /path/to/venv
WSGIPythonPath /path/to/mysite.com
<Directory /path/to/mysite.com/mysite>
<Files wsgi.py>
Require all granted
</Files>
</Directory>The most important directive is WSGIScriptAlias. This maps a specific URL path to your wsgi.py file. In the example above, the first argument (/) tells Apache to serve your application at the root URL.
You also need to tell Apache where your Python code and dependencies live. If you use a virtual environment, you provide its path using WSGIPythonHome. You then use WSGIPythonPath to ensure your project directory is available for import. Finally, you use standard <Directory> and <Files> tags to grant Apache access to the wsgi.py file.
Using Daemon Mode
It is highly recommended to run mod_wsgi in "daemon mode" rather than the default embedded mode. This isolates your Django application in its own background process.
To use daemon mode, you replace the WSGIPythonPath directive with a WSGIDaemonProcess directive that defines your Python paths. You then link your script to this process group.
WSGIDaemonProcess example.com python-home=/path/to/venv python-path=/path/to/mysite.com
WSGIProcessGroup example.com
WSGIScriptAlias / /path/to/mysite.com/mysite/wsgi.pyIf you encounter a UnicodeEncodeError when dealing with file uploads containing non-ASCII characters, you can fix it by adding lang='en_US.UTF-8' and locale='en_US.UTF-8' directly to your WSGIDaemonProcess directive.
WSGIDaemonProcess example.com lang='en_US.UTF-8' locale='en_US.UTF-8'Serving Static and Media Files
Django does not serve static files like images or CSS in a production environment. You must configure Apache to handle these files directly so they bypass the WSGI interface.
You can use the Alias directive to intercept requests for your static and media URLs and map them to the actual folders on your server. You must place these aliases above your WSGIScriptAlias so they take priority.
Alias /robots.txt /path/to/mysite.com/static/robots.txt
Alias /favicon.ico /path/to/mysite.com/static/favicon.ico
Alias /media/ /path/to/mysite.com/media/
Alias /static/ /path/to/mysite.com/static/
<Directory /path/to/mysite.com/static>
Require all granted
</Directory>
<Directory /path/to/mysite.com/media>
Require all granted
</Directory>
WSGIScriptAlias / /path/to/mysite.com/mysite/wsgi.pyTo ensure the styling for the Django admin panel works correctly, you should run the collectstatic management command. This gathers all admin styles into your main static folder so Apache can serve them using the configuration above.
Authenticating Apache against Django
When using Apache and mod_wsgi, you can use Django's authentication system to restrict access to files served directly by Apache. This is very useful if you want to protect static files or other non-Django web applications using your existing Django user database.
You accomplish this using the WSGIAuthUserScript directive in your Apache configuration. You point this directive to a Python script that imports your Django environment and contains a check_password function. Apache will intercept requests to protected URLs and use your Django users to verify the provided credentials before granting access. For more details on this, refer to this Official doc.
