DEV Community

郑沛沛
郑沛沛

Posted on

Docker for Developers: From Dockerfile to Production-Ready Images

Docker isn't just for DevOps teams. Every developer should know how to build efficient, secure container images. Here's a practical guide.

Your First Dockerfile

FROM python:3.12-slim

WORKDIR /app

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

COPY . .

EXPOSE 8000
CMD ["uvicorn", "main:app", "--host", "0.0.0.0", "--port", "8000"]
Enter fullscreen mode Exit fullscreen mode

Multi-Stage Builds

Keep images small by separating build and runtime:

# Stage 1: Build
FROM python:3.12 AS builder
WORKDIR /app
COPY requirements.txt .
RUN pip install --no-cache-dir --prefix=/install -r requirements.txt

# Stage 2: Runtime
FROM python:3.12-slim
WORKDIR /app
COPY --from=builder /install /usr/local
COPY . .
EXPOSE 8000
CMD ["uvicorn", "main:app", "--host", "0.0.0.0", "--port", "8000"]
Enter fullscreen mode Exit fullscreen mode

Result: image goes from 1.2GB to ~200MB.

Layer Caching

Docker caches each layer. Order matters:

# BAD: Any code change invalidates pip install cache
COPY . .
RUN pip install -r requirements.txt

# GOOD: Dependencies cached unless requirements.txt changes
COPY requirements.txt .
RUN pip install -r requirements.txt
COPY . .
Enter fullscreen mode Exit fullscreen mode

Docker Compose for Development

# docker-compose.yml
services:
  app:
    build: .
    ports:
      - "8000:8000"
    volumes:
      - .:/app  # live reload
    environment:
      - DATABASE_URL=postgresql://user:pass@db:5432/mydb
      - REDIS_URL=redis://cache:6379
    depends_on:
      - db
      - cache

  db:
    image: postgres:16
    environment:
      POSTGRES_USER: user
      POSTGRES_PASSWORD: pass
      POSTGRES_DB: mydb
    volumes:
      - pgdata:/var/lib/postgresql/data
    ports:
      - "5432:5432"

  cache:
    image: redis:7-alpine
    ports:
      - "6379:6379"

volumes:
  pgdata:
Enter fullscreen mode Exit fullscreen mode
docker compose up -d
docker compose logs -f app
docker compose exec app python manage.py migrate
Enter fullscreen mode Exit fullscreen mode

Security Best Practices

# Don't run as root
RUN adduser --disabled-password --gecos '' appuser
USER appuser

# Use specific image tags, not :latest
FROM python:3.12.1-slim

# Don't copy secrets into images
# Use .dockerignore
Enter fullscreen mode Exit fullscreen mode
# .dockerignore
.git
.env
__pycache__
*.pyc
node_modules
.venv
Enter fullscreen mode Exit fullscreen mode

Health Checks

HEALTHCHECK --interval=30s --timeout=3s --retries=3 \
    CMD curl -f http://localhost:8000/health || exit 1
Enter fullscreen mode Exit fullscreen mode

Useful Commands

docker build -t myapp:v1 .
docker run -d -p 8000:8000 --name myapp myapp:v1
docker logs -f myapp
docker exec -it myapp bash
docker system prune -a  # clean up everything
docker stats  # live resource usage
Enter fullscreen mode Exit fullscreen mode

Key Takeaways

  1. Use multi-stage builds for smaller images
  2. Order Dockerfile commands for optimal layer caching
  3. Never run containers as root in production
  4. Use .dockerignore to keep images clean
  5. Docker Compose for local development environments

6. Always add health checks for production containers

🚀 Level up your AI workflow! Check out my AI Developer Mega Prompt Pack — 80 battle-tested prompts for developers. $9.99

Top comments (0)