Setting Up a Secure Django Environment with PostgreSQL, Nginx, and Gunicorn on Ubuntu
Introduction
Django is a powerful web framework that allows you to quickly build robust applications in Python. While its local development server is great for development, production environments require a more secure and scalable setup.
In this guide, we'll walk you through the process of deploying a Django project on an Ubuntu server with a PostgreSQL database, using Gunicorn to serve the application and Nginx as a reverse proxy. This setup enhances security and performance by leveraging the strengths of each component.
We'll also discuss how to configure systemd to manage Gunicorn and set up a virtual environment for isolating dependencies.
Prerequisites
An Ubuntu 22.04 server or newer with a non-root user and sudo privileges
An active firewall
A registered domain name (optional but recommended)
Step 1: Install Required Packages
First, update your package lists:
sudo apt update sudo apt upgrade -yNext, install Python, PostgreSQL, and Nginx, along with other dependencies:
sudo apt install python3-venv python3-dev libpq-dev postgresql postgresql-contrib nginx curl -y
Step 2: Configure PostgreSQL Database
Switch to the
postgresuser:sudo -u postgres psqlCreate a new PostgreSQL database and user, replacing
myprojectandmyprojectuserwith your project’s name:CREATE DATABASE myproject; CREATE USER myprojectuser WITH PASSWORD 'password'; ALTER ROLE myprojectuser SET client_encoding TO 'utf8'; ALTER ROLE myprojectuser SET default_transaction_isolation TO 'read committed'; ALTER ROLE myprojectuser SET timezone TO 'UTC'; GRANT ALL PRIVILEGES ON DATABASE myproject TO myprojectuser;Exit the PostgreSQL prompt:
\q
Step 3: Set Up the Python Virtual Environment
Create and navigate to your project directory:
mkdir ~/myprojectdir cd ~/myprojectdirSet up a virtual environment and activate it:
python3 -m venv myprojectenv source myprojectenv/bin/activateInstall Django, Gunicorn, and the PostgreSQL adapter:
pip install django gunicorn psycopg2-binary
Step 4: Create and Configure the Django Project
Start a new Django project:
django-admin startproject myproject .Configure
ALLOWED_HOSTSinmyproject/settings.py:ALLOWED_HOSTS = ['your_domain.com', 'your_server_ip', 'localhost']Set up the PostgreSQL database connection in
myproject/settings.py:DATABASES = { 'default': { 'ENGINE': 'django.db.backends.postgresql', 'NAME': 'myproject', 'USER': 'myprojectuser', 'PASSWORD': 'password', 'HOST': 'localhost', 'PORT': '', } }Set up static files:
STATIC_URL = '/static/' STATIC_ROOT = BASE_DIR / 'static'
Step 5: Complete Django Setup
Migrate the database schema:
python manage.py migrateCreate a Django superuser:
python manage.py createsuperuserCollect static files:
python manage.py collectstatic
Step 6: Test Gunicorn's Ability to Serve the Project
Run Gunicorn to test serving your application:
gunicorn --bind 0.0.0.0:8000 myproject.wsgiVisit
http://your_server_ip:8000to verify that Django is running.
Step 7: Create Gunicorn systemd Socket and Service Files
Create a Gunicorn socket file:
sudo nano /etc/systemd/system/gunicorn.socketAdd the following content:
[Unit] Description=gunicorn socket [Socket] ListenStream=/run/gunicorn.sock [Install] WantedBy=sockets.targetCreate a Gunicorn service file:
sudo nano /etc/systemd/system/gunicorn.serviceAdd the following content, replacing paths and user details as needed:
[Unit] Description=gunicorn daemon Requires=gunicorn.socket After=network.target [Service] User=user_name Group=www-data WorkingDirectory=/home/user_name/myprojectdir ExecStart=/home/user_name/myprojectdir/myprojectenv/bin/gunicorn \ --access-logfile - \ --workers 3 \ --bind unix:/run/gunicorn.sock \ myproject.wsgi:application [Install] WantedBy=multi-user.targetStart and enable the Gunicorn socket:
sudo systemctl start gunicorn.socket sudo systemctl enable gunicorn.socket
Step 8: Configure Nginx as a Reverse Proxy
Create an Nginx configuration file:
sudo nano /etc/nginx/sites-available/myprojectAdd the following content:
server { listen 80; server_name your_domain.com your_server_ip; location / { proxy_pass http://unix:/run/gunicorn.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; } location /static/ { alias /home/awm/myprojectdir/static/; } }Enable the configuration and restart Nginx:
sudo ln -s /etc/nginx/sites-available/myproject /etc/nginx/sites-enabled sudo nginx -t sudo systemctl restart nginx
Step 9: Troubleshoot and Complete Setup
If Nginx or Gunicorn is not running, check their logs:
sudo journalctl -u nginx sudo journalctl -u gunicorn
Following this setup, your Django application will be served through Nginx and Gunicorn, backed by PostgreSQL for database management, and secured on Ubuntu.
Comments
Join the discussionNo comments yet. Be the first to comment.


