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 = Falseand configureALLOWED_HOSTSin production. - Use Gunicorn as the WSGI server — never use
runserverin production. - Run
collectstaticbefore deployment to gather all static files. - Generate
requirements.txtwithpip freezebefore 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
.envfile to.gitignoreto keep secrets safe.
