Docker Compose Dev
Architecture Visual
Docker Compose Dev
Developing modern applications requires more than just your code—you need a Database, a Redis cache, maybe an S3 emulator, and a Mail server. Installing these manually on every developer’s laptop is a recipe for “configuration drift.”
Docker Compose solves this by defining your entire infrastructure in a single YAML file. New hire? Run docker-compose up, and they are productive in minutes.
Architecture
We are automating the “localhost” infrastructure.
- App Service: Your Node/Python/Go code, running with “Hot Reload” enabled.
- Database: Postgres or MySQL, with persistent data in a Docker Volume.
- Cache: Redis for session storage.
- MailHog: A fake SMTP server for testing emails without spamming real users.
Use Cases
- Onboarding: ” clone repo” -> “docker-compose up” -> “ready to code.”
- Integration Testing: Spin up a fresh DB for CI/CD pipelines, run tests, and tear it down.
- Polyglot Teams: Frontend devs don’t need to know how to install Python/Postgres locally; they just “run the container.”
Implementation Guide
We will create a robust environment for a Node.js app + Postgres + Redis + MailHog.
Prerequisites
- Docker Desktop (or Engine)
- Docker Compose
Step 1: Services Definition
Create docker-compose.yml.
version: '3.8'
services:
# 1. The Application with Hot Reload
app:
build:
context: .
dockerfile: Dockerfile.dev
ports:
- "3000:3000"
volumes:
- .:/app
- /app/node_modules # Avoid overwriting container modules
environment:
- DATABASE_URL=postgres://user:password@db:5432/myapp
- REDIS_URL=redis://cache:6379
- SMTP_HOST=mailhog
depends_on:
- db
- cache
# 2. Database
db:
image: postgres:15-alpine
environment:
POSTGRES_USER: user
POSTGRES_PASSWORD: password
POSTGRES_DB: myapp
ports:
- "5432:5432" # Expose to host for GUI tools
volumes:
- postgres_data:/var/lib/postgresql/data
# 3. Cache
cache:
image: redis:7-alpine
# 4. Email Testing
mailhog:
image: mailhog/mailhog
ports:
- "8025:8025" # Dashboard
- "1025:1025" # SMTP
volumes:
postgres_data:
Step 2: Optimizing the Dockerfile
Create Dockerfile.dev. Note that we install devDependencies here (like nodemon).
FROM node:18-alpine
WORKDIR /app
# Copy package.json first to leverage caching
COPY package*.json ./
# Install ALL dependencies (including dev)
RUN npm install
# We DON'T copy the source code here because we bind-mount it in docker-compose
# This makes image build faster and ensures 'hot reload' works.
EXPOSE 3000
# Use nodemon for hot reloading
CMD ["npx", "nodemon", "src/index.js"]
Step 3: Run It
docker-compose up
Access:
- App:
http://localhost:3000 - MailHog UI:
http://localhost:8025
Production Readiness Checklist
Wait, isn’t this for Dev? Yes, but your setup should reflect production reality.
[ ] .dockerignore: Ensure node_modules and .git are ignored to speed up builds.
[ ] Versions: Pin image tags (e.g., postgres:15.2 NOT latest) to match Production DB exactly.
[ ] Database Init: Use /docker-entrypoint-initdb.d/ in Postgres image to seed initial data.
[ ] Healthchecks: Add healthcheck to your service definitions, so app waits until db is actually listening (not just started).
[ ] User Permissions: On Linux, ensure the user ID inside the container matches your host user to avoid file permission errors (user: "${UID}:${GID}").
Cloud Cost Estimator
Dynamic Pricing Calculator