Deploying a Django application can be streamlined using Docker, PostgreSQL, and Nginx. In this guide, we’ll walk through setting up a production-ready Django app on an Ubuntu server with Docker media volume for handling media files.
Prerequisites:
Before starting, ensure you have:
- An Ubuntu server (20.04 or later)
- SSH access
- Docker and Docker Compose installed
- PostgreSQL installed on the remote server
- Nginx installed on the remote server
- A Django project configured for PostgreSQL and Docker
Step 1: Set Up the Ubuntu Server
First, update the system packages:
sudo apt update && sudo apt upgrade -y
Install necessary dependencies:
sudo apt install -y curl git unzip
Ensure Docker is installed:
docker --version
If Docker is not installed, install it using:
curl -fsSL https://get.docker.com | sh
sudo usermod -aG docker $USER
Install Docker Compose:
sudo apt install docker-compose -y
Step 2: Install PostgreSQL on the Remote Server
Install PostgreSQL:
sudo apt install postgresql postgresql-contrib -y
Start and enable PostgreSQL service:
sudo systemctl start postgresql
sudo systemctl enable postgresql
Create a database and user for Django:
sudo -u postgres psql
Inside the PostgreSQL shell, run:
CREATE DATABASE your_db_name;
CREATE USER your_db_user WITH PASSWORD 'your_db_password';
ALTER ROLE your_db_user SET client_encoding TO 'utf8';
ALTER ROLE your_db_user SET default_transaction_isolation TO 'read committed';
ALTER ROLE your_db_user SET timezone TO 'UTC';
GRANT ALL PRIVILEGES ON DATABASE your_db_name TO your_db_user;
\q
Update PostgreSQL to accept external connections:
sudo nano /etc/postgresql/14/main/pg_hba.conf
Modify the following line:
host all all 0.0.0.0/0 md5
Then, update postgresql.conf:
sudo nano /etc/postgresql/14/main/postgresql.conf
Find and modify:
listen_addresses = '*'
Restart PostgreSQL:
sudo systemctl restart postgresql
Step 3: Configure Django to Use Remote PostgreSQL
Update settings.py in your Django project:
DATABASES = {
'default': {
'ENGINE': 'django.db.backends.postgresql',
'NAME': os.getenv('DB_NAME'),
'USER': os.getenv('DB_USER'),
'PASSWORD': os.getenv('DB_PASSWORD'),
'HOST': 'your_remote_postgres_ip',
'PORT': '5432',
}
}
Run migrations:
docker-compose run --rm web python manage.py migrate
Step 4: Set Up Static and Media Files
Create a directory for media files:
mkdir -p ~/django-app/media
Modify docker-compose.yml:
web:
build: .
container_name: django_app
restart: always
env_file: .env
volumes:
- ./media:/app/media
networks:
- django_network
Update settings.py:
MEDIA_URL = '/media/'
MEDIA_ROOT = os.path.join(BASE_DIR, 'media')
Step 5: Install and Configure Nginx on the Remote Server
Install Nginx:
sudo apt install nginx -y
Start and enable Nginx:
sudo systemctl start nginx
sudo systemctl enable nginx
Create an Nginx configuration file for your Django project:
sudo nano /etc/nginx/sites-available/django
Add the following configuration:
server {
listen 80;
server_name yourdomain.com;
location /static/ {
root /home/youruser/django-app;
}
location /media/ {
root /home/youruser/django-app;
}
location / {
proxy_pass http://127.0.0.1:8000;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
}
}
Enable the configuration and restart Nginx:
sudo ln -s /etc/nginx/sites-available/django /etc/nginx/sites-enabled
sudo systemctl restart nginx
Step 6: Deploy the Application
Build and start the Docker container for Django:
docker-compose up -d --build
Check running containers:
docker ps
Run Django collectstatic and create a superuser:
docker-compose exec web python manage.py collectstatic --noinput
docker-compose exec web python manage.py createsuperuser
Restart Nginx:
sudo systemctl restart nginx
Step 7: Secure with SSL (Let’s Encrypt)
Install Certbot:
sudo apt install certbot python3-certbot-nginx -y
Obtain an SSL certificate:
sudo certbot --nginx -d yourdomain.com
Set up auto-renewal:
sudo certbot renew --dry-run