Docker Compose HomeLab Setup: From Zero to 8 Services Behind Cloudflare
Bare-metal Linux → Docker Compose → NGINX reverse proxy → Cloudflare Tunnel. The exact setup running Maalig AI in production.
Docker Compose HomeLab Setup
This is the exact infrastructure setup running Maalig AI in production — no Kubernetes, no managed cloud, just Docker Compose on a bare-metal ASUS server.
The Hardware
ASUS server running Ubuntu 22.04. 32GB RAM, 8-core CPU, 2TB NVMe. More than enough for a SaaS with under 1,000 users.
The Stack
Cloudflare Tunnel
└─ NGINX (reverse proxy)
├─ Angular SSR (web:4000)
└─ NestJS API (api:3000)
├─ MongoDB (27017)
└─ Redis (6379)
Docker Compose Structure
The key insight: separate networks for internal services. MongoDB and Redis are not exposed to the host — only the API container can reach them.
networks:
maalig:
driver: bridge
services:
api:
networks: [maalig]
mongo:
networks: [maalig]
# No ports: exposed to host
redis:
networks: [maalig]
command: redis-server --requirepass ${REDIS_PASSWORD}
Cloudflare Tunnel
No open ports on the server. Cloudflare Tunnel creates an outbound connection to Cloudflare's edge — traffic flows in through the tunnel, never directly to your IP.
cloudflared tunnel create maalig
cloudflared tunnel route dns maalig app.pmpksamy.com
Health Checks
Every service has a health check. Docker restarts unhealthy containers automatically.
healthcheck:
test: wget -qO- http://localhost:3000/api/v1/health | grep -q '"status"'
interval: 15s
timeout: 5s
retries: 3
Rolling Deploy
Zero-downtime deploys: pull new image → restart api → health gate → restart web → verify.
If health check fails at any step, the ERR trap fires the rollback function automatically.