Docker & Containerization

Running Containers in Production

35 min

Where containers run

Option You manage Good for
PaaS with Docker support (Render, Railway, Fly.io) the Dockerfile most small and medium apps
A VPS with Docker Compose the server, updates, backups low cost, full control
Managed container services (AWS ECS/Fargate, Google Cloud Run) cloud configuration scaling, cloud integration
Kubernetes a lot large teams, many services

Start simple. Kubernetes solves problems most small businesses do not have.

A VPS with Compose

services:
  web:
    image: ghcr.io/you/myapp:3f1c2a9
    restart: unless-stopped
    env_file: /srv/myapp/.env
    ports: ["127.0.0.1:8000:8000"]     # only reachable through the reverse proxy
    deploy:
      resources:
        limits: {memory: 512m}

Put a reverse proxy (Caddy or Nginx) in front for HTTPS. Caddy gets certificates automatically:

myapp.com {
    reverse_proxy 127.0.0.1:8000
}

Updating safely

docker compose pull web
docker compose up -d web            # recreates with the new image
docker compose logs -f web

To roll back, change the tag to the previous SHA and run up -d again. Platforms do this with zero downtime by starting the new container, waiting for its health check, then stopping the old one.

Resource limits

Set memory limits so one container cannot starve the server. Size Gunicorn workers to the limit (roughly 100–150 MB per Flask worker), and watch docker stats.

Debugging

docker logs --tail 100 -f web
docker exec -it web sh               # a shell inside the running container
docker inspect web                   # config, env, mounts, health
docker stats                         # live CPU and memory

If a container restarts in a loop, read the logs from the failed run: docker logs web --since 5m.

Data

Containers are disposable; data is not. Databases belong in managed services or named volumes with backups, and uploads in object storage.

Final project

Containerise a Flask + PostgreSQL + Redis app: a multi-stage, non-root image with a health check; Compose for local development; GitHub Actions building, scanning and pushing SHA-tagged images; and a production deploy (PaaS or VPS with Caddy), including a documented rollback to the previous image.

Check yourself

  • Why bind the app port to 127.0.0.1 behind a reverse proxy?
  • How do you roll back a containerised deploy?
  • Where should persistent data live?

Seu progresso fica salvo apenas neste navegador.

Enviar para revisão (10 pontos)