UnderHost
Knowledgebase Docs

Deploy Django Applications on UnderHost VPS

Deploy Django web applications on UnderHost Cloud VPS. Configure Python, Gunicorn, Nginx, PostgreSQL, and static files for production.

On this page

Django is a powerful Python web framework perfect for scalable applications. On UnderHost VPS, you have full control to deploy Django with Gunicorn and Nginx. This guide covers production-ready setup.

Requirements

  • UnderHost Cloud VPS (not available on shared hosting)
  • Python 3.8+ installed (usually included)
  • PostgreSQL or MySQL for database
  • Nginx as reverse proxy
  • SSH access and comfort with command line

Python Virtual Environment

Isolate your Django project dependencies from system Python:

cd /home/username
python3 -m venv myproject_env
source myproject_env/bin/activate

You should see (myproject_env) in your prompt, indicating the virtual environment is active.

Install Dependencies

With virtual environment active, install Django and Gunicorn:

pip install django gunicorn psycopg2-binary

Clone or upload your Django project:

cd /home/username
git clone https://github.com/yourname/myproject.git
cd myproject
pip install -r requirements.txt

Configure Gunicorn

Gunicorn is the application server that runs Django:

gunicorn --bind 127.0.0.1:8000 myproject.wsgi:application

Don't run this directly in production. Create a systemd service (see below).

Setup Nginx Reverse Proxy

Create /etc/nginx/sites-available/myproject:

server {
    listen 80;
    server_name yourdomain.com;

    location / {
        proxy_pass http://127.0.0.1:8000;
        proxy_set_header Host $host;
        proxy_set_header X-Real-IP $remote_addr;
    }

    location /static/ {
        alias /home/username/myproject/static/;
    }
}

Enable and restart Nginx:

sudo ln -s /etc/nginx/sites-available/myproject /etc/nginx/sites-enabled/
sudo systemctl restart nginx

Database Configuration

Update Django settings.py:

DATABASES = {
    'default': {
        'ENGINE': 'django.db.backends.postgresql',
        'NAME': 'myproject_db',
        'USER': 'myproject_user',
        'PASSWORD': 'secure_password',
        'HOST': 'localhost',
        'PORT': '5432',
    }
}

Run s:

python manage.py migrate

Serve Static Files

Configure Django static files:

# settings.py
STATIC_URL = '/static/'
STATIC_ROOT = '/home/username/myproject/static/'
STATIC_FILES_DIRS = [
    '/home/username/myproject/staticfiles/',
]

Collect static files:

python manage.py collectstatic --noinput

Systemd Service

Create /etc/systemd/system/myproject.service:

[Unit]
Description=Django Gunicorn
After=network.target

[Service]
Type=notify
User=username
WorkingDirectory=/home/username/myproject
ExecStart=/home/username/myproject_env/bin/gunicorn \
    --workers 3 \
    --bind 127.0.0.1:8000 \
    myproject.wsgi:application

[Install]
WantedBy=multi-user.target

Enable and start:

sudo systemctl daemon-reload
sudo systemctl enable myproject
sudo systemctl start myproject

Troubleshooting

IssueSolution
502 Bad GatewayCheck Gunicorn running: systemctl status myproject
Static files not loadingRun python manage.py collectstatic
Database connection errorVerify credentials in settings.py, database exists
Permission deniedEnsure user owns /home/username/myproject
Use environment variables for secrets

Never hardcode database passwords in settings.py. Use environment variables: os.environ.get('DB_PASSWORD')

Related: Flask deployment | Python deployment guide | Python on CloudPanel

Was this article helpful?

Need a developer-friendly server?

Use an UnderHost Cloud VPS for SSH, Git, Node.js, Python, Laravel, Docker, cron, and custom development workflows.

Related articles

Back to Developer Tools