DEV Community

Shakhzhakhan Maxudbek
Shakhzhakhan Maxudbek

Posted on • Originally published at args.tech

How to containerize Django application with Docker compose

Why exactly Docker compose? Docker compose used when you want to run your applications on any machine and start it by one click. This way called as serverless and cross platform architecture. Docker allow you to run applications on any computer, where it installed. It's very convenient and simple.

Complete structure of project:

demo_project/
    |
    |-- manage.py
    |
    |-- env/
    |
    |-- backend/
    |     |
    |     |-- asgi.py
    |     |-- __init__.py
    |     |-- settings.py
    |     |-- urls.py
    |     |-- wsgi.py
    |
    |-- core/
    |     |
    |     |-- admin.py
    |     |-- apps.py
    |     |-- __init__.py
    |     |-- models.py
    |     |-- tests.py
    |     |-- views.py
    |
    |-- Dockerfile
    |
    |-- docker-compose.yaml
    |
    |-- nginx/
          |
          |-- default.conf
Enter fullscreen mode Exit fullscreen mode

Start new Django project or open existing.

Create requirements.txt file for dependencies:

django
psycopg
gunicorn
Enter fullscreen mode Exit fullscreen mode

Edit ALLOWED_HOSTS value in settings.py file for listing your domain and IP address:

ALLOWED_HOSTS = [
    '0.0.0.0',
    'localhost',
    'your-domain.com'
]
Enter fullscreen mode Exit fullscreen mode

Docker read content of Dockerfile as instructions and build your own container image. Create Dockerfile in project's root folder with this parameters:

FROM python:latest

ARG APP=/app

ENV PYTHONDONTWRITEBYTECODE=1
ENV PYTHONUNBUFFERED=1

WORKDIR ${APP}

COPY . .

RUN pip install --no-cache-dir -r requirements.txt

CMD ["gunicorn", "--bind", "0.0.0.0:8000", "--workers", "2", "backend.wsgi:application"]
Enter fullscreen mode Exit fullscreen mode

Attention: don't run with python manage.py runserver in production!

Create docker-compose.yaml file in project's root folder and put following values:

services:

  database:
    container_name: database
    image: postgres:latest
    restart: unless-stopped
    shm_size: 128mb
    networks:
      - internal_network
    volumes:
      - /var/lib/postgresql/data/:/var/lib/postgresql/data/
    environment:
      POSTGRES_HOST: database
      POSTGRES_DB: database_name
      POSTGRES_USER: database_user
      POSTGRES_PASSWORD: password
    ports:
      - 127.0.0.1:5432:5432

  backend:
    container_name: backend
    build:
      context: .
      dockerfile: Dockerfile
    restart: unless-stopped
    depends_on:
      - database
    networks:
      - internal_network
    volumes:
      - ./media/:/app/media/
    ports:
      - 127.0.0.1:8000:8000

  nginx:
    container_name: nginx
    image: nginx
    restart: unless-stopped
    depends_on:
      - backend
    networks:
      - internal_network
    volumes:
      - ./nginx/default.conf:/etc/nginx/conf.d/default.conf
    ports:
    - '80:80'
    - '443:443'

networks:
  internal_network:
    ipam:
      driver: default
      config:
        - subnet: 172.18.0.0/24
Enter fullscreen mode Exit fullscreen mode

Create default.conf file insinde of nginx directory:

server {
    listen 80 default_server;

    server_name _;

    location / {
        proxy_set_header Host $host;
        proxy_pass http://backend:8000;
    }
}
Enter fullscreen mode Exit fullscreen mode

Now start application:

docker compose up -d
Enter fullscreen mode Exit fullscreen mode

Top comments (0)