All case studiesLab project
Production Container Infrastructure
A Docker Compose platform running multiple application services with PostgreSQL, MongoDB, Redis, and Kafka behind an Nginx reverse proxy, with health checks, resource limits, and isolated networks.
- Docker
- Docker Compose
- Nginx
- PostgreSQL
- MongoDB
- Redis
- Kafka
This is a personal lab build used to practise and demonstrate the approach. It describes architecture and decisions, not results from a client engagement.
Problem
A multi-service application needed a single, reproducible way to run its APIs, workers, databases, cache, and message broker on one host — without services reaching data stores they had no reason to touch, and without one misbehaving container starving the others.
Architecture
- Edge
- Nginx reverse proxy
- TLS termination
- Application
- API services
- Background workers
- Messaging & cache
- Kafka
- Redis
- Data
- PostgreSQL
- MongoDB
- Named volumes
Technical decisions
- Separate frontend and backend networks
- Only Nginx joins the public-facing network. Data stores live on an internal network with no published ports, so they are reachable only by the services that need them.
- Health checks drive startup order
- depends_on with condition: service_healthy ensures applications start only after their databases and broker actually accept connections, not merely after the container starts.
- Explicit resource limits
- CPU and memory limits on every service keep a runaway worker or query from taking down the whole host.
Implementation
- Wrote multi-stage Dockerfiles to keep runtime images small and free of build tooling.
- Defined services, networks, and named volumes in Compose with environment-specific override files.
- Configured Nginx as the single entry point with upstream health awareness and HTTPS.
- Added health checks and restart policies to every long-running service.
- Documented start-up, upgrade, backup, and recovery procedures.
Security considerations
- No database or broker ports exposed to the host or internet.
- Secrets supplied via environment files excluded from version control.
- Containers run as non-root users where the image supports it.
- TLS terminated at the proxy with HTTP redirected to HTTPS.
Operational benefits
- The full stack starts with one command on any Docker host.
- Failed services restart automatically and dependency order is enforced.
- New engineers can understand the topology from a single Compose file.
Lessons learned
- Health checks must test real readiness — a process being up is not the same as accepting traffic.
- Volume and backup strategy should be designed up front, not after the first data scare.