Dockerizing Django with Postgres, Gunicorn, and Nginx

Dockerizing Django with Postgres, Gunicorn, and Nginx
This is a step-by-step tutorial that details how to configure Django to run on Docker with Postgres. For production environments, we'll add on Nginx and Gunicorn. We'll also take a look at how to serve Django static and media files via Nginx.
Dependencies:
Django v3.2.6 Docker v20.10.8 Python v3.9.6
Project Setup Create a new project directory along with a new Django project:
mkdir django-on-docker && cd django-on-docker
mkdir app && cd app
sudo apt update
sudo add-apt-repository ppa:deadsnakes/ppa
sudo apt update
sudo apt install python3.9 python3.9-venv python3.9-distutils
python3.9 -m venv env
source env/bin/activate
(env)$
(env)$ pip install django==3.2.6
(env)$ django-admin.py startproject hello_django .
(env)$ python manage.py migrate
(env)$ python manage.py runserver
Navigate to http://localhost:8000/ to view the Django welcome screen. Kill the server once done. Then, exit from and remove the virtual environment. We now have a simple Django project to work with from physical/VM server.
Now we are deploying Django app by container.
Now you can delete or modify all the files and folder from the "app" directory or create new directory project. As our environment we have created new directory "django_project"
mkdir -p django_project
Pull your app or project from gitlab/github repository in the "django_project" directory.
Create a requirements.txt file in the "django_project" directory and add Django as a dependency:
mkdir -p django_project
nano requirements.txt
Django==3.0.8
gunicorn==20.0.4
Docker Install Docker, if you don't already have it, then add a Dockerfile to the "django_project" directory:
nano Dockerfile
FROM python:3.8.5-alpine
RUN pip install --upgrade pip
COPY ./requirements.txt .
RUN pip install -r requirements.txt
COPY ./django_project /app
WORKDIR /app
COPY ./entrypoint.sh /
ENTRYPOINT ["sh", "/entrypoint.sh"]
Next, add an entrypoint.sh file to the "django_project" directory to verify that Postgres is healthy before applying the migrations and running the Django development server:
nano entrypoint.sh
#!/bin/sh
python manage.py migrate --no-input
python manage.py collectstatic --no-input
DJANGO_SUPERUSER_PASSWORD=$SUPER_USER_PASSWORD python manage.py createsuperuser --username $SUPER_USER_NAME --email $SUPER_USER_EMAIL --noinput
gunicorn django_project.wsgi:application --bind 0.0.0.0:8000
Save end exit.
Create docker compose file
nano docker-compose.yml
version: '3.7'
services:
django_gunicorn:
volumes:
- static:/static
env_file:
- .env
build:
context: .
ports:
- "8000:8000"
nginx:
build: ./nginx
volumes:
- static:/static
ports:
- "80:80"
depends_on:
- django_gunicorn
volumes:
static:
Save end exit.
Create .env file or modify as your project
nano .env
## do not put this file under version control!
SECRET_KEY='c_r-e8v1divj8y+hu@-w=n#$xj#ciuejybd3_(k2h789(mcv8$'
DEBUG=False
## Super-User Credentials
SUPER_USER_NAME = 'root'
SUPER_USER_PASSWORD = 'root'
SUPER_USER_EMAIL = 'admin@email.com'
Save end exit. Modify the "setting.py" file as requirment. In our environment we have modified the lines below:
nano setting.py
#SECRET_KEY = 'c_r-e8v1divj8y+hu@-w=n#$xj#ciuejybd3_(k2h789(mcv8$'
SECRET_KEY = os.getenv('SECRET_KEY')
#DEBUG = True
DEBUG = os.getenv('DEBUG')
ALLOWED_HOSTS = ['*']
STATIC_ROOT = '/static/'
Crete new folder name "nginx" in the "django_project" directory. Then create default.conf and Dockerfile under "nginx" directory.
nano default.conf
upstream django {
server django_gunicorn:8000;
}
server {
listen 80;
location / {
proxy_pass http://django;
#proxy_pass http://172.16.17.53;
}
location /static/ {
alias /static/;
}
}
Save and exit.
nano Dockerfile
FROM nginx:1.19.0-alpine
COPY ./default.conf /etc/nginx/conf.d/default.conf
Save and exit.
Development Test:
$ docker-compose up -d --build
You should be able to access http://server_ip http://server_ip/admin (credentials mentioned as .env file) http://server_ip:8000



