WSGI (Web Server Gateway Interface) is a specification that defines how web servers communicate with Python web applications. Django uses WSGI as its default interface. In production, Django applications should not be served using runserver
but instead through a WSGI-compatible server like Gunicorn, uWSGI, or mod_wsgi with Apache.
wsgi.py
Django projects include a wsgi.py
file inside the project directory. This file is used to serve the application through WSGI-compatible servers.
import os
from django.core.wsgi import get_wsgi_application
os.environ.setdefault("DJANGO_SETTINGS_MODULE", "myproject.settings")
application = get_wsgi_application()
os.environ.setdefault("DJANGO_SETTINGS_MODULE", "myproject.settings")
: Defines the settings module.get_wsgi_application()
: Creates the WSGI application object.Gunicorn (Green Unicorn) is a popular WSGI server for serving Django applications in production.
pip install gunicorn
gunicorn myproject.wsgi:application --bind 0.0.0.0:8000
myproject.wsgi:application
: Points to the application
object in wsgi.py
.--bind 0.0.0.0:8000
: Binds Gunicorn to all available IPs on port 8000.gunicorn myproject.wsgi:application --workers 4 --bind 0.0.0.0:8000
--workers 4
: Runs Gunicorn with 4 worker processes for handling multiple requests.gunicorn myproject.wsgi:application --daemon
--daemon
: Runs Gunicorn as a background process.Instead of passing all options via the command line, a config file can be used:
# gunicorn_config.py
bind = "0.0.0.0:8000"
workers = 4
timeout = 120
loglevel = "info"
Run Gunicorn with:
gunicorn -c gunicorn_config.py myproject.wsgi:application
uWSGI is another WSGI server that can be used to serve Django applications.
pip install uwsgi
uwsgi --http :8000 --module myproject.wsgi
Instead of passing options in the command, create a uwsgi.ini
file:
[uwsgi]
module = myproject.wsgi
http = :8000
workers = 4
master = true
vacuum = true
Run uWSGI with:
uwsgi --ini uwsgi.ini
mod_wsgi
mod_wsgi
For Apache, the mod_wsgi
module must be installed.
pip install mod_wsgi
mod_wsgi-express module-config
Add this to the Apache configuration file (/etc/httpd/conf/httpd.conf
or /etc/apache2/apache2.conf
):
<VirtualHost *:80>
ServerName example.com
DocumentRoot /path/to/myproject
<Directory /path/to/myproject>
Require all granted
</Directory>
WSGIDaemonProcess myproject python-home=/path/to/venv python-path=/path/to/myproject
WSGIProcessGroup myproject
WSGIScriptAlias / /path/to/myproject/myproject/wsgi.py
</VirtualHost>
Restart Apache:
sudo systemctl restart apache2 # Ubuntu
sudo systemctl restart httpd # CentOS/Rocky Linux
Nginx is a high-performance web server often used as a reverse proxy in front of Gunicorn.
sudo apt install nginx # Ubuntu/Debian
sudo yum install nginx # CentOS/Rocky Linux
Edit /etc/nginx/sites-available/myproject
(or /etc/nginx/conf.d/myproject.conf
):
server {
listen 80;
server_name example.com;
location / {
proxy_pass http://127.0.0.1:8000;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
}
}
Enable the site and restart Nginx:
ln -s /etc/nginx/sites-available/myproject /etc/nginx/sites-enabled/
sudo systemctl restart nginx
For automatic startup, create a systemd
service file /etc/systemd/system/myproject.service
:
[Unit]
Description=Gunicorn server for Django project
After=network.target
[Service]
User=www-data
Group=www-data
WorkingDirectory=/path/to/myproject
ExecStart=/path/to/venv/bin/gunicorn --workers 4 --bind 0.0.0.0:8000 myproject.wsgi:application
Restart=always
[Install]
WantedBy=multi-user.target
Enable and start the service:
sudo systemctl daemon-reload
sudo systemctl enable myproject
sudo systemctl start myproject
Check status:
sudo systemctl status myproject
journalctl -u myproject --no-pager
sudo tail -f /var/log/nginx/error.log
gunicorn myproject.wsgi:application --bind 127.0.0.1:8000
wsgi.py
Manuallypython myproject/wsgi.py