Design a Docker Compose development environment that mirrors production as closely as possible for a microservices application with 8 services, including hot-reload, shared networks, health checks, and dependency ordering. How do you handle the 'works on my machine' problem?
Quick Answer
Use Docker Compose with service profiles for optional services, health-check-based dependency ordering (depends_on with condition: service_healthy), bind mounts with watch mode for hot-reload, shared networks mimicking production topology, and environment-specific override files (docker-compose.override.yml).
Detailed Answer
Architecture for Dev-Prod Parity
The goal is for local development to match production topology (same service mesh, same database engines, same queue systems) while enabling fast iteration (hot-reload, debug ports, verbose logging).
Compose File Strategy
- docker-compose.yml: Base configuration matching production (images, networks, health checks) - docker-compose.override.yml: Development overrides (bind mounts, debug ports, hot-reload) - docker-compose.prod.yml: Production-specific (replicas, resource limits, secrets from vault) - Use profiles to make heavyweight services optional (e.g., ML service only started when needed)
Dependency Management
Don't use depends_on alone (only waits for container start, not readiness). Use depends_on with condition: service_healthy so services wait for actual readiness. Define health checks that verify the service can accept connections.
Hot-Reload Pattern
Bind-mount source code into containers and run in development mode. Use docker compose watch (Compose 2.22+) for file sync with rebuild triggers. For compiled languages (Go, Java), use air/nodemon equivalent inside the container.
Networking
Create separate networks mirroring production topology (frontend, backend, data). Services only connect to networks they need. This catches network isolation bugs early.
Solving 'Works on My Machine'
1. Pin ALL image versions (no latest tags) 2. Use .env file for environment variables with .env.example in git 3. Use docker compose config to validate the resolved configuration 4. Include a Makefile or Taskfile with standard commands (make up, make test, make reset) 5. Document resource requirements (Docker Desktop needs 8GB+ RAM for 8 services)