Django Deployment

You have built your Django project and tested it locally at http://127.0.0.1:8000/. Now it is time to deploy it — make it accessible to the world on a real web address. Deployment means moving your project from your local computer to a live server on the internet. This lesson walks you through the complete process step by step.

What is Deployment?

Deployment is the process of making your Django application available on the internet so real users can access it from any device, anywhere in the world. The development server (runserver) is only for local testing — it is not suitable, secure, or fast enough for real-world use.

Example: Building a Django app locally is like rehearsing a play in your living room. Deployment is opening the theatre to the public. The rehearsal space is fine for practice, but the actual show needs a proper stage, lighting, seating, and security — all of which is what a production server provides.

What Changes Between Development and Production?

Several settings must change when going from local development to a live server:

  • DEBUG must be set to False — in production, Django must not show detailed error pages to users.
  • ALLOWED_HOSTS must include your domain name.
  • Static files must be collected and served by the web server (not Django).
  • Database is usually switched from SQLite (development) to PostgreSQL (production).
  • SECRET_KEY must be kept private — never expose it in code repositories.

Step 1 — Update settings.py for Production


# Production settings

DEBUG = False

ALLOWED_HOSTS = ['yourdomain.com', 'www.yourdomain.com', 'your-server-ip']

# Keep SECRET_KEY private — load from environment variable
import os
SECRET_KEY = os.environ.get('DJANGO_SECRET_KEY', 'fallback-key-for-dev-only')

# Production database — PostgreSQL
DATABASES = {
    'default': {
        'ENGINE': 'django.db.backends.postgresql',
        'NAME': os.environ.get('DB_NAME'),
        'USER': os.environ.get('DB_USER'),
        'PASSWORD': os.environ.get('DB_PASSWORD'),
        'HOST': os.environ.get('DB_HOST', 'localhost'),
        'PORT': os.environ.get('DB_PORT', '5432'),
    }
}

Step 2 — Install a Production WSGI Server

Django's built-in runserver is not suitable for production. You need a proper WSGI server. Gunicorn is the most popular choice:


pip install gunicorn

Test that Gunicorn can serve your app:


gunicorn myschool.wsgi:application

Gunicorn runs your Django app efficiently and can handle many requests at the same time, unlike the development server.

Example: The Django development server is like a single chef serving one table at a time. Gunicorn is like a full restaurant kitchen with multiple chefs working in parallel — able to serve many customers simultaneously without anyone waiting too long.

Step 3 — Collect Static Files

In production, the web server (Nginx) serves static files, not Django. First collect all static files into one folder:


# In settings.py
STATIC_ROOT = os.path.join(BASE_DIR, 'staticfiles')

# Run this command before deploying
python manage.py collectstatic

This copies all CSS, JS, and images from all your apps into the staticfiles/ folder.

Step 4 — Set Up a requirements.txt

Before deploying, generate a file listing all Python packages your project needs. The server uses this to install the exact same packages:


pip freeze > requirements.txt

On the server, install them with:


pip install -r requirements.txt

Step 5 — Choose a Hosting Platform

There are several hosting options for Django projects. Here are the most popular ones for beginners:

Option A — Railway (Easiest for Beginners)

  • Connect your GitHub repository directly.
  • Railway auto-detects Django and handles most of the configuration.
  • Has a free tier for small projects.
  • Best choice for beginners who want to deploy fast without server management.

Option B — PythonAnywhere (Beginner-Friendly)

  • Built specifically for Python and Django applications.
  • Has a free tier with one web app.
  • Good web-based dashboard — no need to use command line for most tasks.
  • Best for small to medium projects and learning deployments.

Option C — Render

  • Modern platform with good free tier support.
  • Supports PostgreSQL databases.
  • Connects to GitHub for automatic deployments on every code push.

Option D — VPS (DigitalOcean, Linode, AWS EC2)

  • A Virtual Private Server gives you full control over your server.
  • You install and configure everything yourself — Nginx, Gunicorn, PostgreSQL.
  • More complex but gives maximum flexibility and performance.
  • Best for experienced developers or larger production applications.

Step 6 — Deploying on PythonAnywhere (Example Walkthrough)


1. Create a free account at pythonanywhere.com

2. Open a Bash console and clone your project:
   git clone https://github.com/yourusername/myschool.git

3. Create a virtual environment:
   python -m venv venv
   source venv/bin/activate

4. Install requirements:
   pip install -r requirements.txt

5. Run database migrations:
   python manage.py migrate

6. Collect static files:
   python manage.py collectstatic

7. Go to the "Web" tab in PythonAnywhere dashboard
8. Create a new web app — choose "Manual configuration" and select your Python version
9. Set the WSGI configuration file to point to your Django project
10. Set the virtual environment path
11. Set static files URL (/static/) and directory path
12. Reload the web app — your site is live!

Step 7 — Using Environment Variables for Secrets

Never put your SECRET_KEY, database passwords, or email passwords directly in settings.py. Use environment variables instead. A popular tool for managing this is python-decouple:


pip install python-decouple

Create a .env file in your project root (never commit this to Git):


# .env file
DJANGO_SECRET_KEY=your-very-long-secret-key-here
DEBUG=False
DB_NAME=myschool_db
DB_USER=admin
DB_PASSWORD=superSecretPassword123

In settings.py:


from decouple import config

SECRET_KEY = config('DJANGO_SECRET_KEY')
DEBUG = config('DEBUG', default=False, cast=bool)

Add .env to your .gitignore file so it is never uploaded to GitHub:


# .gitignore
.env
Example: Hiding secrets in environment variables is like keeping the vault combination in a sealed envelope in the bank manager's private safe — not written on the vault door itself where anyone can see it.

Pre-Deployment Checklist


Before going live, confirm all of the following:

[ ] DEBUG = False in settings.py
[ ] ALLOWED_HOSTS includes your domain name
[ ] SECRET_KEY is stored safely (not in code or GitHub)
[ ] requirements.txt is up to date (pip freeze > requirements.txt)
[ ] python manage.py migrate has been run on the server
[ ] python manage.py collectstatic has been run
[ ] Database is set up and connected (PostgreSQL recommended)
[ ] Admin superuser has been created on the server
[ ] .env file is in .gitignore and not uploaded to GitHub

Quick Recap

  • Set DEBUG = False and configure ALLOWED_HOSTS in production.
  • Use Gunicorn as the WSGI server — never use runserver in production.
  • Run collectstatic before deployment to gather all static files.
  • Generate requirements.txt with pip freeze before deploying.
  • Use PythonAnywhere or Railway for beginner-friendly deployment.
  • Never put secrets (SECRET_KEY, passwords) directly in settings.py — use environment variables.
  • Always add your .env file to .gitignore to keep secrets safe.

Leave a Comment

Your email address will not be published. Required fields are marked *