Docker for Development
Docker gives you reproducible environments — no more "works on my machine." Here's a practical setup for Django projects.
Dockerfile
FROM python:3.12-slim
WORKDIR /app
# Install dependencies first (layer caching)
COPY requirements.txt .
RUN pip install --no-cache-dir -r requirements.txt
# Copy application code
COPY . .
# Collect static files at build time
RUN python manage.py collectstatic --noinput
EXPOSE 8000
CMD ["gunicorn", "myproject.wsgi:application", "--bind", "0.0.0.0:8000"]
Docker Compose for Local Dev
# docker-compose.yml
services:
web:
build: .
command: python manage.py runserver 0.0.0.0:8000
volumes:
- .:/app # Live reload
ports:
- "8000:8000"
environment:
- DEBUG=1
- DATABASE_URL=sqlite:///data/storydatabase.sqlite
Key Principles
Layer ordering matters. Put things that change least (OS, dependencies) at the top. Application code goes last. This maximizes cache hits:
# Changes rarely → cached
COPY requirements.txt .
RUN pip install -r requirements.txt
# Changes often → rebuilt
COPY . .
Use .dockerignore. Keep images small:
.git
__pycache__
*.pyc
.env
node_modules
data/*.sqlite
Development vs. Production. Use docker-compose.override.yml for dev-only settings:
# docker-compose.override.yml (auto-loaded in dev)
services:
web:
command: python manage.py runserver 0.0.0.0:8000
volumes:
- .:/app
environment:
- DEBUG=1
Useful Commands
# Build and start
docker compose up --build
# Run management commands
docker compose exec web python manage.py migrate
docker compose exec web python manage.py seed_content
# Shell into container
docker compose exec web bash
# View logs
docker compose logs -f web