Skip to main content

Command Palette

Search for a command to run...

Dockerizing Django with Postgres, Gunicorn, and Nginx

Updated
3 min read
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

More from this blog

M

My DevOps Blog

10 posts