{
“@context”: “https://schema.org”,
“@type”: “TechArticle”,
“headline”: “How to Use Docker Compose for Local Development in 2026: Complete Guide”,
“description”: “Master Docker Compose for local dev in 2026 โ multi-service setup, hot reload, networking, volumes, secrets, and production parity.”,
“url”: “https://techpulsesite.com/how-to-use-docker-compose-for-local-development-in-2026-complete-guide/”,
“datePublished”: “2026-06-28T10:05:00+00:00”,
“dateModified”: “2026-06-29T04:14:19+00:00”,
“author”: {
“@type”: “Organization”,
“name”: “TechPulse Editorial Team”,
“url”: “https://techpulsesite.com”
},
“publisher”: {
“@type”: “Organization”,
“name”: “TechPulse”,
“url”: “https://techpulsesite.com”
},
“inLanguage”: “en”
}
{
“@context”: “https://schema.org”,
“@type”: “FAQPage”,
“mainEntity”: [
{
“@type”: “Question”,
“name”: “Docker Compose vs Kubernetes for local dev?”,
“acceptedAnswer”: {
“@type”: “Answer”,
“text”: “Docker Compose for local development. Kubernetes for production. Minikube or k3d for testing Kubernetes configs locally. Compose is simpler, faster, and sufficient for dev workflows.”
}
},
{
“@type”: “Question”,
“name”: “Why is my code change not reflected even with volume mounts?”,
“acceptedAnswer”: {
“@type”: “Answer”,
“text”: “Hot reload depends on the framework (FastAPI –reload, Next.js dev server). If not working, check the volume mount path is correct and the container’s working directory matches. Also restart the service: docker compose restart backend.”
}
},
{
“@type”: “Question”,
“name”: “How do I run database migrations automatically?”,
“acceptedAnswer”: {
“@type”: “Answer”,
“text”: “Add a command in your service or use a separate migration service: docker compose run –rm backend alembic upgrade head. Or add it to entrypoint.sh before starting the server.”
}
},
{
“@type”: “Question”,
“name”: “How do I share data between services?”,
“acceptedAnswer”: {
“@type”: “Answer”,
“text”: “Via named volumes for database data. Via environment variables for configuration. Via the network for service-to-service communication. Avoid bind-mounting files between containers โ use the service API instead.”
}
},
{
“@type”: “Question”,
“name”: “How do I debug a service running in Docker?”,
“acceptedAnswer”: {
“@type”: “Answer”,
“text”: “Map the debugger port in your compose file, configure your IDE (VS Code’s Remote – Containers or Python debugpy). Or exec into the container: docker compose exec backend bash.”
}
}
]
}
{
“@context”: “https://schema.org”,
“@type”: “TechArticle”,
“headline”: “How to Use Docker Compose for Local Development in 2026: Complete Guide”,
“description”: “Master Docker Compose for local dev in 2026 โ multi-service setup, hot reload, networking, volumes, secrets, and production parity.”,
“url”: “https://techpulsesite.com/how-to-use-docker-compose-for-local-development-in-2026-complete-guide/”,
“datePublished”: “2026-06-28T10:05:00+00:00”,
“dateModified”: “2026-06-29T02:28:53+00:00”,
“author”: {
“@type”: “Organization”,
“name”: “TechPulse Editorial Team”,
“url”: “https://techpulsesite.com”
},
“publisher”: {
“@type”: “Organization”,
“name”: “TechPulse”,
“url”: “https://techpulsesite.com”
},
“inLanguage”: “en”
}
{
“@context”: “https://schema.org”,
“@type”: “FAQPage”,
“mainEntity”: [
{
“@type”: “Question”,
“name”: “Docker Compose vs Kubernetes for local dev?”,
“acceptedAnswer”: {
“@type”: “Answer”,
“text”: “Docker Compose for local development. Kubernetes for production. Minikube or k3d for testing Kubernetes configs locally. Compose is simpler, faster, and sufficient for dev workflows.”
}
},
{
“@type”: “Question”,
“name”: “Why is my code change not reflected even with volume mounts?”,
“acceptedAnswer”: {
“@type”: “Answer”,
“text”: “Hot reload depends on the framework (FastAPI –reload, Next.js dev server). If not working, check the volume mount path is correct and the container’s working directory matches. Also restart the service: docker compose restart backend.”
}
},
{
“@type”: “Question”,
“name”: “How do I run database migrations automatically?”,
“acceptedAnswer”: {
“@type”: “Answer”,
“text”: “Add a command in your service or use a separate migration service: docker compose run –rm backend alembic upgrade head. Or add it to entrypoint.sh before starting the server.”
}
},
{
“@type”: “Question”,
“name”: “How do I share data between services?”,
“acceptedAnswer”: {
“@type”: “Answer”,
“text”: “Via named volumes for database data. Via environment variables for configuration. Via the network for service-to-service communication. Avoid bind-mounting files between containers โ use the service API instead.”
}
},
{
“@type”: “Question”,
“name”: “How do I debug a service running in Docker?”,
“acceptedAnswer”: {
“@type”: “Answer”,
“text”: “Map the debugger port in your compose file, configure your IDE (VS Code’s Remote – Containers or Python debugpy). Or exec into the container: docker compose exec backend bash.”
}
}
]
}
{
“@context”: “https://schema.org”,
“@type”: “FAQPage”,
“mainEntity”: [
{
“@type”: “Question”,
“name”: “Docker Compose vs Kubernetes for local dev?”,
“acceptedAnswer”: {
“@type”: “Answer”,
“text”: “Docker Compose for local development. Kubernetes for production. Minikube or k3d for testing Kubernetes configs locally. Compose is simpler, faster, and sufficient for dev workflows.”
}
},
{
“@type”: “Question”,
“name”: “Why is my code change not reflected even with volume mounts?”,
“acceptedAnswer”: {
“@type”: “Answer”,
“text”: “Hot reload depends on the framework (FastAPI –reload, Next.js dev server). If not working, check the volume mount path is correct and the container’s working directory matches. Also restart the service: docker compose restart backend.”
}
},
{
“@type”: “Question”,
“name”: “How do I run database migrations automatically?”,
“acceptedAnswer”: {
“@type”: “Answer”,
“text”: “Add a command in your service or use a separate migration service: docker compose run –rm backend alembic upgrade head. Or add it to entrypoint.sh before starting the server.”
}
},
{
“@type”: “Question”,
“name”: “How do I share data between services?”,
“acceptedAnswer”: {
“@type”: “Answer”,
“text”: “Via named volumes for database data. Via environment variables for configuration. Via the network for service-to-service communication. Avoid bind-mounting files between containers โ use the service API instead.”
}
},
{
“@type”: “Question”,
“name”: “How do I debug a service running in Docker?”,
“acceptedAnswer”: {
“@type”: “Answer”,
“text”: “Map the debugger port in your compose file, configure your IDE (VS Code’s Remote – Containers or Python debugpy). Or exec into the container: docker compose exec backend bash.”
}
}
]
}
{
“@context”: “https://schema.org”,
“@type”: “TechArticle”,
“headline”: “How to Use Docker Compose for Local Development in 2026: Complete Guide”,
“description”: “Master Docker Compose for local dev in 2026 โ multi-service setup, hot reload, networking, volumes, secrets, and production parity.”,
“url”: “”,
“datePublished”: “2026-06-28 10:05:00”,
“dateModified”: “2026-06-28 10:05:00”,
“author”: {
“@type”: “Organization”,
“name”: “TechPulse Editorial Team”,
“url”: “https://techpulsesite.com”
},
“publisher”: {
“@type”: “Organization”,
“name”: “TechPulse”,
“url”: “https://techpulsesite.com”,
“logo”: {
“@type”: “ImageObject”,
“url”: “https://techpulsesite.com/wp-content/uploads/logo.png”
}
}
}
Docker Compose transforms local development from “works on my machine” to reproducible, production-like environments that every team member can spin up in minutes. In 2026, with Docker Compose v2 built into Docker Desktop and CLI, there’s no better tool for managing multi-service local stacks.
๐ Table of Contents
- Why Docker Compose for Development?
- Project Setup: Full-Stack Application
- Core docker-compose.yml
- Development Dockerfile for Hot Reload
- Override File for Local Customization
- Essential Commands
- Managing Secrets Properly
- Networking Between Services
- Health Checks and Service Dependencies
- Production vs Development Compose Files
- Frequently Asked Questions
- Conclusion
๐ Key Takeaway
Docker Compose transforms local development from “works on my machine” to reproducible, production-like environments that every team member can spin up in minutes. In 2026, with Docker Compose v2 built into Docker Desktop and CLI, there’s no bette…
Why Docker Compose for Development?
- Spin up Postgres, Redis, your API, and a queue worker with one command
- Eliminate “it works on my machine” โ every developer has identical environments
- Match production service topology locally without running Kubernetes
- Easily switch between Node versions, database versions, or service configurations
Project Setup: Full-Stack Application
We’ll build a compose setup for: Next.js frontend, FastAPI backend, PostgreSQL, Redis, and a Celery worker.
myapp/
โโโ docker-compose.yml
โโโ docker-compose.override.yml # local dev overrides
โโโ frontend/
โ โโโ Dockerfile
โ โโโ ...
โโโ backend/
โ โโโ Dockerfile
โ โโโ ...
โโโ .env.local
Core docker-compose.yml
version: "3.9"
services:
# โโ PostgreSQL โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
db:
image: postgres:15-alpine
environment:
POSTGRES_DB: ${DB_NAME:-myapp}
POSTGRES_USER: ${DB_USER:-postgres}
POSTGRES_PASSWORD: ${DB_PASS:-devpassword}
volumes:
- postgres_data:/var/lib/postgresql/data
- ./backend/scripts/init.sql:/docker-entrypoint-initdb.d/init.sql
ports:
- "5432:5432"
healthcheck:
test: ["CMD-SHELL", "pg_isready -U postgres"]
interval: 5s
timeout: 5s
retries: 5
# โโ Redis โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
redis:
image: redis:7-alpine
ports:
- "6379:6379"
command: redis-server --maxmemory 256mb --maxmemory-policy allkeys-lru
# โโ FastAPI Backend โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
backend:
build:
context: ./backend
dockerfile: Dockerfile.dev
volumes:
- ./backend:/app # hot reload: source mounted
ports:
- "8000:8000"
environment:
DATABASE_URL: postgresql://postgres:devpassword@db:5432/myapp
REDIS_URL: redis://redis:6379/0
ENV: development
depends_on:
db:
condition: service_healthy
redis:
condition: service_started
command: uvicorn app.main:app --host 0.0.0.0 --port 8000 --reload
# โโ Celery Worker โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
worker:
build:
context: ./backend
dockerfile: Dockerfile.dev
volumes:
- ./backend:/app
environment:
DATABASE_URL: postgresql://postgres:devpassword@db:5432/myapp
REDIS_URL: redis://redis:6379/0
depends_on: [db, redis]
command: celery -A app.tasks worker --loglevel=info
# โโ Next.js Frontend โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
frontend:
build:
context: ./frontend
dockerfile: Dockerfile.dev
volumes:
- ./frontend:/app
- /app/node_modules # anonymous volume prevents override
ports:
- "3000:3000"
environment:
NEXT_PUBLIC_API_URL: http://localhost:8000
command: npm run dev
volumes:
postgres_data:
Development Dockerfile for Hot Reload
# backend/Dockerfile.dev
FROM python:3.11-slim
WORKDIR /app
COPY requirements.txt .
RUN pip install -r requirements.txt
# Don't copy source โ it's mounted as volume for hot reload
CMD ["uvicorn", "app.main:app", "--host", "0.0.0.0", "--reload"]
# frontend/Dockerfile.dev
FROM node:20-alpine
WORKDIR /app
COPY package*.json ./
RUN npm install
# Source mounted as volume; node_modules stays in container
CMD ["npm", "run", "dev"]
Override File for Local Customization
# docker-compose.override.yml (not committed to git)
# Each developer's personal overrides
services:
backend:
environment:
DEBUG: "true"
LOG_LEVEL: debug
ports:
- "8000:8000"
- "5678:5678" # debugger port
db:
ports:
- "5432:5432" # expose to host for TablePlus/DBeaver access
Docker Compose automatically merges docker-compose.override.yml with the base file โ no need to specify -f.
Essential Commands
# Start everything
docker compose up -d
# View logs (all services)
docker compose logs -f
# View logs for one service
docker compose logs -f backend
# Run a command in a service
docker compose exec backend python manage.py migrate
docker compose exec db psql -U postgres -d myapp
# Rebuild a specific service after Dockerfile change
docker compose up -d --build backend
# Stop and remove everything (keep volumes)
docker compose down
# Stop, remove containers AND volumes (fresh slate)
docker compose down -v
# Scale a service
docker compose up -d --scale worker=3
Managing Secrets Properly
# .env.local (gitignored)
DB_PASS=mylocalsecretpassword
SECRET_KEY=dev-only-not-production
# docker-compose.yml references env vars
environment:
DB_PASS: ${DB_PASS}
# Or use Docker secrets for production-like setups
secrets:
db_password:
file: ./secrets/db_password.txt
services:
backend:
secrets: [db_password]
Networking Between Services
Services in the same Compose file communicate by service name. Your backend connects to PostgreSQL at db:5432, not localhost:5432. This matches production container networking exactly:
# backend connects to other services by service name
DATABASE_URL=postgresql://postgres:pass@db:5432/myapp
REDIS_URL=redis://redis:6379/0
# NOT localhost โ that would be the container itself
# NOT the host IP โ that breaks portability
Health Checks and Service Dependencies
services:
backend:
depends_on:
db:
condition: service_healthy # waits for DB to pass healthcheck
redis:
condition: service_started # just waits for container to start
db:
healthcheck:
test: ["CMD-SHELL", "pg_isready -U postgres"]
interval: 5s
retries: 5
start_period: 10s
Production vs Development Compose Files
# Use specific files explicitly
docker compose -f docker-compose.yml up -d # dev
docker compose -f docker-compose.yml -f docker-compose.prod.yml up -d # prod
# In production: remove volume mounts, use built images, add resource limits
# docker-compose.prod.yml
services:
backend:
image: myapp-backend:1.2.0 # pinned production image
restart: unless-stopped
deploy:
resources:
limits:
memory: 512m
Frequently Asked Questions
Q: Docker Compose vs Kubernetes for local dev?
A: Docker Compose for local development. Kubernetes for production. Minikube or k3d for testing Kubernetes configs locally. Compose is simpler, faster, and sufficient for dev workflows.
Q: Why is my code change not reflected even with volume mounts?
A: Hot reload depends on the framework (FastAPI –reload, Next.js dev server). If not working, check the volume mount path is correct and the container’s working directory matches. Also restart the service: docker compose restart backend.
Q: How do I run database migrations automatically?
A: Add a command in your service or use a separate migration service: docker compose run --rm backend alembic upgrade head. Or add it to entrypoint.sh before starting the server.
Q: How do I share data between services?
A: Via named volumes for database data. Via environment variables for configuration. Via the network for service-to-service communication. Avoid bind-mounting files between containers โ use the service API instead.
Q: How do I debug a service running in Docker?
A: Map the debugger port in your compose file, configure your IDE (VS Code’s Remote – Containers or Python debugpy). Or exec into the container: docker compose exec backend bash.
Conclusion
Docker Compose is the definitive tool for local multi-service development in 2026. The setup in this guide โ base compose file + override file + proper volume mounts + healthchecks โ gives you production parity locally, hot reload for fast development, and a one-command start for new team members. Invest 2-3 hours setting this up properly and save hundreds of hours of “it works on my machine” debugging.
๐ You might also like
๐ Share this article




โ๏ธ Leave a Comment