Preloader
Logo

Office Address

14/22AB4, 2nd Floor, KC Arcade
CSEZ, 24/1701, Kochi
Kerala, India

Phone Number

+91 96555 10508

+91 77362 51469

Email Address

business@cybosys.in

Setting Up a Django Application with PostgreSQL, Nginx, and Gunicorn on Ubuntu

This guide walks you through deploying a Django web application using PostgreSQL, Gunicorn, and Nginx on Ubuntu.

🔧 Project Structure
- Django Project Root: /var/www/project_name/src/
- Virtual Environment: /var/www/project_name/venv/
- manage.py is located inside src/

Step 0: Prepare Project Directory & Clone Code

# Create project folder and navigate
sudo mkdir -p /var/www/project_name/src
cd /var/www/project_name

# Create virtual environment
python3 -m venv venv

# Activate the environment
source venv/bin/activate

# Move to source directory
cd src

# Initialize Git and pull code
git init
git remote add origin https://your-repo-url.git
git checkout -b production
git pull origin production

Step 1: Install Required Packages

sudo apt update
sudo apt install python3-pip python3-dev libpq-dev postgresql postgresql-contrib nginx curl

Step 2: Configuring PostgreSQL

PostgreSQL will store your application’s data. Create a database and user for your project.

Log in to PostgreSQL:

sudo -u postgres psql

Inside the PostgreSQL prompt, run:

-- Create a database
CREATE DATABASE myproject;

-- Create a user with a secure password
CREATE USER myprojectuser WITH ENCRYPTED PASSWORD 'your_secure_password';

-- Grant privileges and set ownership
GRANT ALL PRIVILEGES ON DATABASE myproject TO myprojectuser;
ALTER DATABASE myproject OWNER TO myprojectuser;

-- Exit PostgreSQL
\q

Step 3: Set Up Your Django Project

cd /var/www/project_name
source venv/bin/activate
cd src/
pip install -r requirements.txt

Update project_name/settings.py with your database config:

DATABASES = {
    'default': {
        'ENGINE': 'django.db.backends.postgresql',
        'NAME': 'myproject',
        'USER': 'myprojectuser',
        'PASSWORD': 'your_secure_password',
        'HOST': 'localhost',
        'PORT': '5432',
    }
}

python manage.py makemigrations
python manage.py migrate

# Before running collectstatic, ensure this is in settings.py:
# If your 'static/' folder is at the same level as manage.py:
STATICFILES_DIRS = [os.path.join(BASE_DIR, 'static')]
STATIC_ROOT = os.path.join(BASE_DIR, 'static')
STATIC_URL = '/static/'

python manage.py collectstatic

Step 4: Set Up Gunicorn

cd /var/www/project_name
source venv/bin/activate
pip install gunicorn
cd src
gunicorn --workers 3 --bind unix:/var/www/project_name/gunicorn.sock project_name.wsgi:application

(Replace project_name.wsgi with the actual Python path to your WSGI module.)

Step 5: Create Gunicorn systemd Socket and Service

We will use systemd to manage the Gunicorn process. This includes creating both a socket unit (to listen for connections) and a service unit (to launch Gunicorn).

➤ Create the Gunicorn Socket Unit

Start by creating and opening a systemd socket file for Gunicorn:

sudo nano /etc/systemd/system/gunicorn.socket

Paste the following content:

[Unit]
Description=gunicorn socket

[Socket]
ListenStream=/run/gunicorn.sock

[Install]
WantedBy=sockets.target

This socket will listen for incoming connections and activate the Gunicorn service only when needed. Save and close the file after editing.

➤ Create the Gunicorn Service Unit

Next, create the Gunicorn service file:

sudo nano /etc/systemd/system/gunicorn.service

Paste the following content:

[Unit]
Description=gunicorn daemon
After=network.target

[Service]
User=root
Group=www-data
WorkingDirectory=/var/www/project_name/src
ExecStart=/var/www/project_name/venv/bin/gunicorn --access-logfile - --workers 3 --bind unix:/var/www/project_name/gunicorn.sock project_name.wsgi:application

[Install]
WantedBy=multi-user.target

Make sure to replace project_name with your actual Django project name or path.

🛠️ Note: You should use a non-root user (e.g., www-data) for security in production, instead of User=root.

After saving both files, continue with starting and enabling the socket and verifying that Gunicorn is working properly (see Gunicorn verification section above).

🧪 Verifying Gunicorn Socket Activation

Once your gunicorn.service and gunicorn.socket files are set up, start and enable the socket unit:

sudo systemctl start gunicorn.socket
sudo systemctl enable gunicorn.socket

This sets up the socket to listen for incoming requests and automatically trigger Gunicorn when needed.

You can confirm the socket is working by checking its status:

sudo systemctl status gunicorn.socket

If everything is configured correctly, the socket should be active (listening). Next, verify that the socket file has been created:

file /run/gunicorn.sock

If the socket is missing or the service is failing, check the logs for more detail:

sudo journalctl -u gunicorn.socket

Ensure the /etc/systemd/system/gunicorn.socket file is correct before proceeding.

🔁 Testing Gunicorn Socket Activation

At this stage, gunicorn.service may still be inactive. That’s expected if it hasn’t yet received any connections. You can check this with:

sudo systemctl status gunicorn

Now test the socket by sending a request to it using curl:

curl --unix-socket /run/gunicorn.sock localhost

If everything is working, you should see HTML output from your Django application, and Gunicorn should now be active. Confirm it with:

sudo systemctl status gunicorn

If any issues arise, inspect Gunicorn’s logs:

sudo journalctl -u gunicorn

If you’ve made changes to your service file, be sure to reload systemd and restart Gunicorn:

sudo systemctl daemon-reload
sudo systemctl restart gunicorn

🔍 Tip: Make sure the socket file and service configuration are correct before continuing with the Nginx configuration.

Step 6: Configure Nginx

sudo nano /etc/nginx/sites-available/project_name

Paste:

server {
    listen 80;
    server_name yourdomain.com;

    location = /favicon.ico { access_log off; log_not_found off; }
    location /static/ {
        root /var/www/project_name/src;
    }

    location / {
        include proxy_params;
        proxy_pass http://unix:/run/gunicorn.sock;
    }

    client_max_body_size 100M;
}
sudo ln -s /etc/nginx/sites-available/project_name /etc/nginx/sites-enabled
sudo nginx -t
sudo systemctl reload nginx

✅ Your Django App is Now Deployed!

💡 Want HTTPS? Add Let's Encrypt with Certbot for a free SSL certificate.

Share:

Request A Call Back

Ever find yourself staring at your computer screen a good consulting slogan to come to mind? Oftentimes.