Running Containers in Production
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.1behind a reverse proxy? - How do you roll back a containerised deploy?
- Where should persistent data live?
يُحفظ تقدّمك في هذا المتصفح فقط.
إرسال للمراجعة (10 نقطة)