Docker Compose for Django development

I had to get Docker Compose working for a Django project, primarily to make it easier for other developers to get a working development environment.

Some features of this project:

I ended up with this docker-compose.yml file in the root of the project:

version: "3.1"

volumes:
  postgresql-data:
services:
  database:
    image: postgis/postgis:13-3.1
    restart: always
    expose:
      - "5432"
    ports:
      - "5432:5432"
    volumes:
      - postgresql-data:/var/lib/postgresql/data
    environment:
      POSTGRES_USER: postgres
      POSTGRES_DB: mydb
      POSTGRES_PASSWORD: postgres
  web:
    container_name: myapp
    platform: linux/amd64
    build:
      context: .
      dockerfile: Dockerfile.dev
    command: python manage.py runserver 0.0.0.0:3000
    environment:
      DATABASE_URL: postgres://postgres:postgres@database:5432/mydb
      DEBUG: 1
    volumes:
      - .:/app
    ports:
      - "3000:3000"
    depends_on:
      - migrations
      - database
  migrations:
    platform: linux/amd64
    build:
      context: .
      dockerfile: Dockerfile.dev
    command: python manage.py migrate --noinput
    environment:
      DATABASE_URL: postgres://postgres:postgres@database:5432/mydb
    volumes:
      - .:/app
    depends_on:
      - database

The db container runs PostGIS. It uses a named volume to persist PostgreSQL data in between container restarts.

The web container runs the Django development server, built using the custom Dockerfile.dev Dockerfile.

The migrations container simply runs the apps migrations and then terminates - with depends_on used to ensure that migrations run after the hdatabase server starts and before the web server.

Both web and migrations include a platform: linux/amd64 property - this ensures they will work on M1 Macs even if the Python dependencies are not yet easily compiled for that architecture, see Running Docker on an M1 Mac.

The container_name: myapp field on the web container is a convenience which means you can later run commands like this:

docker exec -it myapp ./manage.py collectstatic

Here's Dockerfile.dev:

FROM python:3.9-slim

ENV APP_HOME /app
WORKDIR $APP_HOME

ENV PYTHONUNBUFFERED 1

# gdal for GeoDjango
RUN apt-get update && apt-get install -y \
    binutils \
    gdal-bin \
    libproj-dev \
    git \
    && rm -rf /var/lib/apt/lists/*

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

WORKDIR $APP_HOME/myapp

RUN ./manage.py collectstatic --no-input

CMD python manage.py runserver 0.0.0.0:3000

Created 2021-05-24T22:08:23-07:00, updated 2021-05-26T11:32:27-07:00 · History · Edit