What is Docker Compose?

Docker Compose is a tool for defining and running multi-container applications. With a single docker-compose.yml file, you define your entire application stack — web servers, databases, caches, and other services — along with how they connect and communicate. A single docker-compose up command starts everything.

Docker Compose is ideal for local development environments, CI/CD pipelines, and even small production deployments. It eliminates the "it works on my machine" problem by ensuring every developer uses the same environment configuration.

Common Docker Compose Stacks

  • Node.js + PostgreSQL + Redis: A typical REST API backend with relational storage and caching
  • Python + MySQL: Common for Django or Flask web applications
  • Nginx + Node.js: Nginx as a reverse proxy in front of your Node.js application
  • Full-stack: Nginx + Node.js + PostgreSQL + Redis: Production-like setup with reverse proxy, API, database, and cache

Docker Compose Volumes & Networks Tips

  • Always use named volumes for database data to persist between container restarts
  • Use custom bridge networks for service-to-service communication — services can reach each other by service name
  • Use .env files for sensitive values (passwords, API keys) instead of hardcoding in compose files
  • Set restart: unless-stopped for production services to auto-restart on failure
  • Use healthcheck to delay dependent services until your database is ready

Frequently Asked Questions about Docker Compose

What is the difference between docker compose up and docker compose start?

docker compose up creates and starts containers from scratch, pulling or building images as needed. docker compose start only restarts containers that were previously created and stopped — it cannot create new ones. Use docker compose up -d for detached (background) mode. Add --build to force image rebuilds when your Dockerfile changes.

How do services communicate with each other in Docker Compose?

Services on the same Docker Compose network reach each other using the service name as the hostname. If your database service is named db, your application connects to db:5432 instead of localhost:5432. Docker Compose automatically creates a default bridge network for all services defined in the same compose file. You can create custom named networks for more control.

How do I persist database data between container restarts?

Use named volumes in your compose file. Without a volume, all data inside a container is lost when it stops. Define a volume under the service: volumes: - postgres_data:/var/lib/postgresql/data, then declare it at the top level: volumes: postgres_data:. Named volumes are managed by Docker and persist across docker compose down — only docker compose down -v removes them.

What does restart: unless-stopped mean in Docker Compose?

restart: unless-stopped means Docker will automatically restart the container if it crashes or if the Docker daemon restarts (e.g., after a server reboot), but it will not restart a container that you explicitly stopped with docker compose stop. This is the recommended setting for production services. Other options: no (never restart), always (always restart, even after explicit stop), on-failure (restart only on non-zero exit code).

Related Developer Tools