Deployment with Gunicorn and Nginx in Django
Deploying a Django application with Gunicorn and Nginx is a common and efficient setup for production environments. Gunicorn serves as the WSGI server for running your Django application, while Nginx acts as a reverse proxy server to handle client requests and serve static files. In this article, we'll guide you through the steps to deploy a Django project using Gunicorn and Nginx.
1. Prerequisites
Before you begin, ensure you have the following prerequisites:
- A Django project that is ready for production
- Access to a server (e.g., a VPS) running a Linux distribution (Ubuntu is commonly used)
- Root or sudo access to install software and configure the server
- Python 3 and pip installed on the server
- Gunicorn and Nginx installed on the server
2. Install Gunicorn
Gunicorn is a Python WSGI HTTP server that serves your Django application. It is a robust server that can handle multiple requests concurrently. To install Gunicorn, use pip:
pip install gunicorn
3. Install and Configure Nginx
Nginx is a powerful web server that is commonly used as a reverse proxy for Python web applications. It will forward client requests to Gunicorn and can also serve static files directly. To install Nginx, run:
sudo apt update
sudo apt install nginx
Once Nginx is installed, you need to configure it to work with Gunicorn. First, create an Nginx configuration file for your project in the /etc/nginx/sites-available/
directory. Then, create a symbolic link to enable the site:
sudo nano /etc/nginx/sites-available/myproject
In this file, add the following configuration:
server {
listen 80;
server_name yourdomain.com www.yourdomain.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;
proxy_set_header X-Forwarded-Proto $scheme;
}
location /static/ {
alias /path/to/your/project/static/;
}
location /media/ {
alias /path/to/your/project/media/;
}
}
Make sure to replace yourdomain.com
with your actual domain name and update the paths for your static and media files.
Next, enable the site by creating a symbolic link to the /etc/nginx/sites-enabled/
directory:
sudo ln -s /etc/nginx/sites-available/myproject /etc/nginx/sites-enabled/
Finally, test the Nginx configuration and restart the service to apply changes:
sudo nginx -t
sudo systemctl restart nginx
4. Configure Gunicorn
Now that Nginx is configured, you need to set up Gunicorn to serve your Django application. In your project directory, run the following command to start Gunicorn:
gunicorn --workers 3 myproject.wsgi:application
This command runs Gunicorn with 3 worker processes, but you can adjust the number of workers depending on the number of CPU cores available on your server. Gunicorn listens on port 8000 by default, which matches the proxy pass setting in the Nginx configuration.
5. Create a Gunicorn Systemd Service
To run Gunicorn as a service, you can create a systemd service file. This will allow Gunicorn to start automatically when the server boots and makes it easier to manage. Create a new service file for Gunicorn in the /etc/systemd/system/
directory:
sudo nano /etc/systemd/system/gunicorn.service
In this file, add the following content, adjusting the paths as necessary:
[Unit]
Description=gunicorn daemon for Django project
After=network.target
[Service]
User=youruser
Group=yourgroup
WorkingDirectory=/path/to/your/project
ExecStart=/path/to/your/virtualenv/bin/gunicorn --workers 3 --bind unix:/path/to/your/project/myproject.sock myproject.wsgi:application
[Install]
WantedBy=multi-user.target
Replace youruser
, yourgroup
, and other paths with the appropriate values for your setup.
Once the service file is created, reload systemd to apply the changes, enable the service, and start it:
sudo systemctl daemon-reload
sudo systemctl enable gunicorn
sudo systemctl start gunicorn
To check the status of the Gunicorn service, run:
sudo systemctl status gunicorn
6. Configure Nginx to Use Gunicorn via Unix Socket
It is recommended to use a Unix socket for communication between Nginx and Gunicorn for better performance. Update your Nginx configuration to proxy requests to the Unix socket instead of port 8000:
location / {
proxy_pass http://unix:/path/to/your/project/myproject.sock;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
}
Don't forget to restart Nginx after updating the configuration:
sudo systemctl restart nginx
7. Finalizing Static and Media Files
In production, you need to serve static files separately from Gunicorn. To do this, Django provides a collectstatic
command that gathers all static files into a single directory:
python manage.py collectstatic
Make sure that Nginx is serving static files from the correct directory as defined in your Nginx configuration:
location /static/ {
alias /path/to/your/project/static/;
}
8. Securing the Application with HTTPS
In a production environment, you should secure your application with HTTPS. You can easily obtain a free SSL certificate using Let's Encrypt and configure Nginx to serve your site over HTTPS. Install Certbot and obtain the certificate:
sudo apt install certbot python3-certbot-nginx
sudo certbot --nginx -d yourdomain.com -d www.yourdomain.com
Certbot will automatically configure Nginx to redirect HTTP traffic to HTTPS and handle SSL certificate renewal.
9. Conclusion
Deploying a Django application using Gunicorn and Nginx provides a robust, scalable solution for production environments. Gunicorn handles the application server side, while Nginx efficiently handles static files, SSL termination, and reverse proxying. By following the steps above, you can deploy your Django application securely and efficiently.