DeveloperApril 2026 · 7 min read

How to Build Docker Compose Files (2026)

Docker Compose defines your entire application stack in a single YAML file. Instead of running docker commands for each container, docker compose up starts everything — your app, database, cache, and any other services — with one command. This guide covers the essential Docker Compose concepts for building reliable multi-container setups.

🐳
Try the Docker Compose Builder
Free, no signup
DG
Derek Giordano
Designer & Developer
In this guide
01Defining Services02Ports & Volumes03Environment & Dependencies04Essential Commands
⚡ Key Takeaways
  • Create docker-compose.
  • Covers defining services.
  • Covers ports and volumes.
  • Covers environment variables and dependencies.
  • Covers essential docker compose commands.

Defining Services

Each service in docker-compose.yml represents a container. The service name becomes the container's hostname on the Docker network. A typical web application has three services: the app itself, a database, and possibly a cache.

The image property specifies which Docker image to use. Use official images with version tags: postgres:15, redis:7-alpine, node:18-alpine. Avoid using 'latest' in production — pin specific versions for reproducibility.

Alpine-based images (-alpine suffix) are significantly smaller than standard images. node:18-alpine is about 120MB compared to 900MB+ for the standard image. Use Alpine unless you need specific packages that require a full Linux distribution.

Ports and Volumes

Port mapping follows the host:container pattern. ports: "3000:3000" maps port 3000 on your machine to port 3000 in the container. You can use different ports: "8080:3000" maps your port 8080 to the container port 3000.

💡 Tip
Always include -webkit-backdrop-filter alongside backdrop-filter for Safari support. Without the prefix, the effect is invisible to roughly 25% of mobile users.

Volumes persist data between container restarts. Without volumes, database data is lost every time the container stops. Named volumes (pgdata:/var/lib/postgresql/data) are managed by Docker and survive container recreation.

Bind mounts (./src:/app/src) map host directories into the container. Use these for development so code changes are reflected instantly without rebuilding the image. Do not use bind mounts in production.

Environment Variables and Dependencies

Environment variables configure services without modifying images. Set database passwords, API keys, and feature flags through environment or env_file properties. Use env_file: .env to load from a file rather than listing them inline.

⚠ Warning
On iOS Safari, backdrop-filter inside a position: fixed element can cause severe scroll performance issues. Test thoroughly on real iOS devices.

depends_on controls startup order. If your app needs the database, add depends_on: - db. Docker Compose starts the database before the app. Note: depends_on waits for the container to start, not for the service to be ready. Your app should implement connection retry logic.

Healthchecks verify a service is actually ready, not just running. Add healthcheck with a test command (like pg_isready for PostgreSQL). Combined with depends_on condition: service_healthy, this ensures services wait for true readiness.

Essential Docker Compose Commands

docker compose up -d starts all services in detached mode (background). Add --build to rebuild images before starting. This is your primary command for launching the stack.

docker compose down stops and removes all containers. Add -v to also remove volumes (caution: this deletes all data). Use docker compose stop to stop without removing containers.

docker compose logs -f follows the log output from all services. Add a service name to filter: docker compose logs -f web shows only the web service logs. Essential for debugging startup issues.

docker compose exec web sh opens a shell inside a running container. Use this to inspect files, run commands, or debug issues inside the container environment.

Frequently Asked Questions

What Docker Compose version should I use?+
Modern Docker Compose (v2) no longer requires a version field. If you include one, version: '3.8' is widely compatible.
How do containers communicate?+
Docker Compose creates a network for all services. Containers reach each other by service name: the web service connects to the database at db:5432.
What is the difference between volumes and bind mounts?+
Named volumes are Docker-managed and persist data reliably. Bind mounts map host directories into containers, useful for development but less portable.
Should I use Docker Compose in production?+
For simple deployments, yes. For complex production systems, consider Kubernetes or a managed container service. Docker Compose is excellent for development and small-scale production.
Try it yourself

Build docker-compose.yml visually — free, no signup.

⚡ Open Docker Compose Builder
DG
Derek Giordano
Written by the creator of Ultimate Design Tools. BA in Business Marketing.
📚 References & Further Reading