How to use Docker Compose for multi-container application orchestration

What is Docker Compose?

Imagine you're baking a complex cake. You don't just mix flour and eggs separately; you follow a single recipe that lists all ingredients (containers) and the exact steps to bring them together in the right order. That recipe is Docker Compose.

You already know how to run a single container with docker run. But a real application—like a web app with a frontend, backend API, database, and cache—needs several containers. Manually running a dozen commands, linking networks, and mounting volumes is error-prone and hard to share.

The "Recipe" Approach

The Hard Way (Manual)
docker run --name db ...
docker run --name api ...
docker network create ...

Easy to forget a step!

The Compose Way (Recipe)
docker-compose.yml
services:
  web: nginx
  db: postgres

Docker Compose solves this. It's a tool that reads a single docker-compose.yml file—your "recipe"—and automatically creates, starts, and connects all your containers as one defined application. You describe the desired state (e.g., "I need a web service, a PostgreSQL database, and they must share a network"), and Compose handles the execution.

⚠️ A Common Misconception

"Docker Compose is only for development."

This stems from its simplicity. Yes, it's perfect for local development because you can spin up an entire stack with one command. But that doesn't mean it's unfit for production.

Development

Ideal for rapid iteration. Spin up/down instantly.

Production

Perfect for single-server deployments and CI/CD pipelines. It manages the lifecycle of containers on a single host robustly.

Note: For orchestrating across many servers (a cluster), you would eventually use Kubernetes or Docker Swarm. But for a single-server production app, Compose is a robust, declarative tool.

The Anatomy of docker-compose.yml

The power is in the file's structure. It's declarative YAML. You don't write scripts; you define what you want.

docker-compose.yml
# 1. Schema version
version: '3.8'

# 2. Services (The Containers)
services:
  web:
    image: nginx:alpine
    ports:
      - "8080:80"
    depends_on:
      - db # Wait for DB first
    environment:
      DB_HOST: db # Connect via service name

  db:
    image: postgres:15
    volumes:
      - db_data:/var/lib/postgresql/data

# 3. Volumes (Persistent Storage)
volumes:
  db_data:

Visualizing Dependencies & Networking

Why structure matters: Compose creates a default network. Services can reach each other by name (e.g., db). depends_on controls the order.

postgres (db) Stopped
nginx (web) Stopped

1. db starts first.

2. web waits, then starts.

3. Connection opens automatically.

📦 Services

The heart of the file. Each key (like web, db) defines one container. You configure it with an image or build context, ports, and environment variables.

🌐 Automatic Networking

Compose creates a default network. Any service can reach another simply by using its service name as the hostname. You don't need manual --link flags.

💾 Volumes

Declaring a named volume (like db_data) tells Compose to manage the storage lifecycle. This ensures your database data survives container restarts.

⏱️ Dependencies

depends_on controls startup order. It waits for the container to start. For complex waits (e.g., waiting for DB to be ready to accept connections), you'd add a health check.

You don't need to memorize every option. The pattern is: under a service, you specify the container's image, its ports, environment variables, and any dependencies. Compose translates this blueprint into the equivalent docker run commands, network creation, and volume setup.

Why use Docker Compose for multi-container apps?

Imagine a software team with three members: Alice (Frontend), Bob (Backend), and Charlie (Database).

Without a project manager, you—the developer—are stuck doing the coordination:

  • Telling Alice exactly where Bob's workstation is located.
  • Ensuring Alice starts her shift only after Bob is ready to accept requests.
  • Manually running cables (networks) and setting up shared whiteboards (volumes) between them.

Doing this once is messy. Doing it every time you reboot your computer is a nightmare.

Docker Compose is your project manager. It reads a single blueprint (docker-compose.yml) and handles all that coordination automatically.

The "Project Manager" Effect

Without Compose (You are the Manager)
docker network create my_net
docker run -d --name db --network my_net ...
docker run -d --name api --network my_net ...

High cognitive load. Easy to forget a flag.

With Compose (The Blueprint)
services:
  db: postgres
  api: node:14

When you run docker compose up, Compose acts as the orchestrator. It creates a dedicated, isolated network for your application and plugs every service into it automatically.

The Internal Reasoning: What You Gain

1. Service Discovery

Compose handles DNS resolution. Your web service can talk to your db service simply by using the hostname db. No IP addresses needed.

2. Unified Lifecycle

docker compose down tears down everything—containers, networks, and volumes. No leftover "zombie" resources cluttering your machine.

3. Shareable Config

The entire stack architecture lives in one file. Your teammate clones the repo and runs docker compose up to get the exact same environment.

Visualizing Service Discovery

The Magic: In a normal Docker run, you'd have to manually map networks. In Compose, the web container just knows the name db. Let's simulate a connection request.

Container: db Ready
Container: web Idle

Notice: No IP address needed. Just the name.

⚠️ Common Pitfall: The Sledgehammer

Don't use a sledgehammer to crack a nut.

If your application is truly a single container (e.g., just a static Nginx site), a docker-compose.yml file is overkill. A simple docker run -p 8080:80 nginx:alpine is perfectly fine and more direct.

Rule of Thumb

Introduce Docker Compose the moment you need more than one container that must communicate. The moment you think, "I need a database too," or "I need a separate cache service," that's Compose's sweet spot.

Performance Considerations

Because Compose manages a single, dedicated network per project, inter-service communication is extremely efficient.

  • Bridge Network: Containers talk to each other directly over a virtual bridge network inside the host. This is faster than publishing ports to the host's public interface and having traffic loop back in.
  • Overhead: The only "cost" is the abstraction layer itself—Compose translates your YAML into Docker API calls. This overhead is negligible (milliseconds) compared to the time you save.
Traffic Path Comparison
Manual
Host Loopback
Container A Slower
Compose
Bridge Net
Container B Faster

Core concepts of docker orchestration with Docker Compose

To truly understand Docker Compose, imagine your application is a small city. In this city, every component has a specific role and infrastructure.

You don't just throw buildings (containers) on a field; you plan the infrastructure.

The City Blueprint

Services (Buildings)

Your web and db containers. Each is a self-contained unit with a specific job.

Networks (Roads)

The invisible infrastructure that lets buildings find each other. Compose builds a private road for your app automatically.

Volumes (Warehouses)

Permanent storage outside the buildings. If a building is destroyed (container removed), the data in the warehouse remains safe.

This trio—Services, Networks, Volumes—is the fundamental building block model. You declare them in your docker-compose.yml, and Compose constructs the city.

⚠️ The Scaling Misconception

"Docker Compose is a cluster manager."

This is a common trap. While you can run docker compose up --scale web=3, this simply creates 3 identical copies of the container on the same single host.

Docker Compose (Single Host)

Manages lifecycle on one server. No load balancer, no self-healing across machines. Perfect for dev or simple production on one VPS.

Kubernetes / Swarm (Cluster)

Manages containers across many servers. Handles load balancing, self-healing, and scheduling across a fleet of machines.

Professor's Note: Think of Compose as the architect for a single building. Kubernetes is the city planner for an entire metropolis. Don't use a city planner to build a house.

Advanced: Dependency Management

You know depends_on controls order. But order isn't enough.
Starting a container is not the same as the service being ready.

The "Ready State" Problem

The Scenario: Your Web App tries to connect to the Database.
The Issue: The Database container might be "Running" (started) but still initializing its files. If Web connects too early, it crashes.

postgres (db) Initializing...
nginx (web) Waiting...

Notice: Web waits for Healthy, not just Running.

The Code Solution

To fix this, we combine depends_on with a healthcheck. This tells Compose: "Wait until the database actually says 'I am ready'."

docker-compose.yml
# 1. Define the Health Check for the Database
db:
  image: postgres:15
  healthcheck:
    test: ["CMD-SHELL", "pg_isready -U postgres"]
    interval: 10s
    timeout: 5s
    retries: 5

# 2. Tell Web to wait for that specific health status
web:
  image: my-app
  depends_on:
    db:
      condition: service_healthy # <--- The Magic Key

Setting up your first Docker Compose example

Let's stop theorizing and start building. Imagine you need to create a small web application: a Python Flask API that needs a PostgreSQL database to store user data.

Without Compose, you'd be juggling two separate docker run commands, manually creating a network, and linking them.

With Compose, you simply draw the blueprint.

Your docker-compose.yml file becomes the architect. You list the "buildings" (services) and declare how they connect.

The Critical Rule: File Location

Professor's Warning: This is the #1 mistake beginners make. docker compose up looks for the blueprint in your current directory.

❌ The Wrong Way
📁 my-project/
📄 app.py
📄 .gitignore
📁 ~/desktop/
📄 docker-compose.yml (Too far away!)
Error: Compose cannot find docker-compose.yml.
✅ The Right Way
📁 my-project/
📄 docker-compose.yml
📄 app.py
📄 .env
Success: Compose finds the blueprint immediately.

Advanced: Handling Secrets Securely

Never hardcode secrets (like database passwords) directly into your docker-compose.yml. If you commit that file to GitHub, your password is public.

Instead, use a .env file. Think of it as a secure bridge that connects your local secrets to the container configuration.

Visualizing the Secure Bridge

The Flow: Compose reads the .env file, substitutes the variable in the YAML, and passes the secret to the container.

.env file Secret Source
docker-compose.yml Waiting...
Container (Postgres) Empty

Notice how the password never appears in the YAML file code.

docker-compose.yml
# 1. The Blueprint (YAML)
services:
  db:
    image: postgres:15
    environment:
      POSTGRES_PASSWORD: ${POSTGRES_PASSWORD} # Placeholder

# 2. The Secure Source (.env)
# POSTGRES_PASSWORD=super_secret_123

Writing the docker-compose.yml file

When you write a docker-compose.yml file, you are not writing a script. You are not telling Docker how to do things step-by-step.

Instead, you are drawing a blueprint.

Think of yourself as an architect. You don't lay the bricks yourself (that's the image's job). You simply draw the plan: "I need a web building and a db building, and they must be connected by a pipe."

This is called Declarative Configuration. You declare what you want, and Compose figures out how to build it.

The Blueprint Validator

Professor's Warning: YAML is whitespace-sensitive. Indentation is not optional; it defines the structure. A single misplaced space can break your entire application.

broken-compose.yml
services:
web:
image: nginx
db:
image: postgres
perfect-compose.yml
services:
web:
image: nginx
db:
image: postgres

In the example above, db is indented differently than web. To YAML, this means db is a sibling of services, not a child. Compose will crash. Always use 2 spaces per level and never use tabs.

Advanced: Understanding Version 3

You might see a line at the very top: version: '3.8'.

This tells Compose which schema (rulebook) to follow. Version 3 is the modern standard for single-host orchestration. It unlocks powerful features that older versions don't support.

Health Checks

Allows you to define how to check if a service is actually ready (e.g., "ping the database"). This makes depends_on much smarter.

Named Volumes

Top-level definitions for persistent storage. You can define complex storage drivers and options here, ensuring your data survives container restarts.

Resource Limits

You can limit CPU and Memory usage per container (e.g., "This service can only use 512MB RAM"). This prevents one app from eating all your server's resources.

Professor's Tip: Unless you are working on a legacy project, always use version: '3.8' (or higher). It is the sweet spot for modern features and stability.

Managing networks and volumes in multi-container docker

Imagine your computer is a large city. Without Docker Compose, every container is a house with a direct line to the street. It's chaotic.

Docker Compose builds gated communities.

When you run docker compose up, Compose creates a private, isolated network for that specific project. Inside this community, your services (Web, DB, Cache) have private roads connecting them. They can talk freely using simple names like db or web.

But crucially, Project A's community is walled off from Project B's. This prevents your Flask app from accidentally connecting to your WordPress app's database.

Visualizing Network Isolation

Project A
Web App
DB (internal)
Project B
API
DB (internal)

Try to send a request from Project A to Project B.

Notice: The "Wall" blocks the request.

Inside a project, services see each other. Across projects, they are invisible.

The Danger: Shared Volumes

By default, Compose creates named volumes scoped to your project (e.g., myproject_db_data). This is safe.

However, if you explicitly declare a volume as external: true, you are telling Compose: "Don't create a new one, use this existing one."

If two different projects use the same external volume, they will both try to write to the same disk space. This leads to data corruption or security leaks.

Volume Collision Risk
Shared Volume

Status: Safe (Empty)

Advanced: Custom Network Drivers

While the default bridge network is perfect for 95% of use cases, you might encounter advanced scenarios requiring custom configurations.

Custom Subnets

If your host machine already uses the default Docker range (e.g., 172.17.0.0/16), you can define a custom IP range to avoid conflicts.

Macvlan

Gives your containers their own physical MAC address and IP on your LAN. Makes containers look like physical devices on your network.

Overlay

Used for Swarm or Kubernetes clusters. It allows containers on different physical servers to talk as if they were on the same LAN.

docker-compose.yml
# Defining a custom network
networks:
  custom-net:
    driver: bridge
    ipam:
      config:
        - subnet: "172.28.0.0/16"

services:
  web:
    image: nginx
    networks:
      - custom-net

Deploying to production: devops with docker

Moving your docker-compose.yml from your laptop to a production server feels like taking a recipe you perfected in a test kitchen and using it to run a busy restaurant.

The core ingredients (services, networks, volumes) are the same, but the stakes are higher. You now need reliability (the app must stay up), security (secrets must be protected), and resource discipline (one container shouldn't starve the others of CPU or memory).

Docker Compose handles this transition gracefully. You're not changing the tool; you're adding production-grade configuration to your blueprint.

The Scope Difference: Building vs. City

Docker Compose

Perfectly manages all apartments in a single building (one host).

  • One Server (VM)
  • Simple Lifecycle
  • No Load Balancing

Kubernetes / Swarm

Manages an entire city of buildings (a cluster of hosts).

  • Many Servers (Cluster)
  • Self-Healing
  • Load Balancing

⚠️ Rule of Thumb: If you need more than one server to handle traffic, Compose is not enough. You need a cluster orchestrator.

Advanced: The "Swarm Bridge"

Docker Swarm is Docker's native clustering solution. Interestingly, a docker-compose.yml file is almost a valid Swarm deployment file.

The key is the deploy section. In a single-host Compose context, these keys are ignored. But when you deploy to a Swarm cluster, they become active rules.

Visualizing the "Deploy" Section

The Magic: The same file works for both. Toggle the mode below to see how Compose ignores specific lines locally, but Swarm activates them.

Local Machine Active
Swarm Cluster Inactive

Local: deploy is ignored.

Swarm: deploy controls resources.

docker-compose.yml (Universal)
# 1. The Service Definition
web:
  image: my-app:prod
  
  # 2. The "Deploy" Section (Swarm Magic)
  deploy:
    restart_policy:
      condition: any # Swarm uses this
    resources:
      limits:
        cpus: '0.50'
        memory: 512M

  # 3. The Network (Overlay for Swarm)
  networks:
    - app-network

Professor's Note: This is a smooth path for teams wanting clustering without leaving the Docker ecosystem. Develop and test locally with docker compose. When ready for multi-host production, initialize Swarm and deploy the same file as a stack.

Debugging and troubleshooting common failures

When your Docker Compose app fails, don't panic. Treat your application like a patient in a hospital. You don't just guess what's wrong; you run specific tests to isolate the problem.

Your "City" (services, networks, volumes) has specific checkpoints. You need to check them in order:

  1. Is the blueprint valid? (Syntax check)
  2. Did the containers start? (Status check)
  3. Why did they crash? (Log analysis)
  4. Is the wiring broken? (Network/Volume check)

Follow this evidence trail. Most failures are either configuration errors (bad YAML), permission issues (can't write to a folder), or connectivity problems (can't find the database).

The Debugging Simulator: "My App Won't Start"

Scenario: You ran docker compose up, but the app is down. Follow the Professor's checklist to diagnose it.

Terminal
root@host:~/my-app$ docker compose up -d
Creating network "my-app_default" ... done
Creating my-app_db_1 ... done
Creating my-app_web_1 ... done
Error: my-app_web_1 exited with code 1

Step 1: Check the Blueprint

Is the YAML file valid?

Step 2: Check Status

Did the containers start?

Step 3: Check Logs

What error message did it give?

Step 4: The Fix

Apply the solution found in logs.

The "Permission Denied" Trap

The most common failure for beginners is the Bind Mount Permission Error.

Imagine you tell Docker: "Mount my local folder ./data into the container's folder /var/lib/postgresql/data."

Here is the problem:

  • On your computer (Host): The folder is owned by You (UID 1000).
  • Inside the container: The database runs as user postgres (UID 999).

When the container tries to write to the folder, the Host says: "Stop! You are UID 999, but this folder belongs to UID 1000. Permission Denied."

Visualizing the Permission Wall

❌ Bind Mount (The Trap)
Host Folder (./data)
Owner: You (UID 1000)
BLOCKED: Permission Denied
Container (postgres)
User: postgres (UID 999)
✅ Named Volume (The Fix)
Docker Volume (db_data)
Managed by Docker
ALLOWED: Matches User
Container (postgres)
User: postgres (UID 999)

Rule of Thumb: Use Named Volumes for databases. Let Docker manage the permissions. Use Bind Mounts only for code you need to edit live, and be ready to fix permissions if you get "Permission Denied".

The Doctor's Toolkit: Quick Reference

Keep this table handy. When something breaks, pick the tool that answers your specific question.

Command Question it Answers What to Look For
docker compose config "Is my YAML file valid?" If this fails, fix syntax errors first. It prints the final config with env vars resolved.
docker compose ps "Are my containers running?" Look for Exit Code 1. This means the main process crashed.
docker compose logs -f "Why did it crash?" The why is always here. Look for "Connection Refused", "Permission Denied", or "Syntax Error".
docker compose events "What is happening in real-time?" Shows the raw stream of events (create, start, die). Good for race conditions.
docker compose exec web bash "Can I get inside to debug?" Gives you a shell inside the container. Run ping db to test connectivity manually.

Scaling and updating services (when should I use or avoid this?)

Imagine your Docker Compose application is a single, robust apartment building.

Scaling with --scale is like adding more identical apartments *inside that same building*. You can run multiple copies of your web service container on the same host to handle more load.

But if your "building" is full and you need to construct an entire new building across the street (a second server), Compose cannot do that. That requires a city planner—a cluster orchestrator like Kubernetes or Docker Swarm.

The Scaling Limit: One Host vs. Many

Single Server (Host)
Web Service (1)
Ready to scale...

Try to scale your application. Notice what happens when you hit the limit of a single server.

Professor's Insight: Compose manages containers on one host. If you need to spread load across multiple physical servers, you must switch to Kubernetes or Swarm.

Common Misconception: The "Magic" Autoscaler

A critical misunderstanding is that --scale provides automatic, load-based scaling like a cloud autoscaler.

It does not.

docker compose up --scale web=3 is a manual, static instruction: "Start exactly three copies of the web service right now."

Compose will not monitor CPU usage or request volume and adjust the number of containers. It also does not provide a built-in load balancer to distribute traffic between those three web containers. You must place a reverse proxy (like Nginx or Traefik) in front of them yourself.

The Load Balancer Gap
Users
Web 1
Receiving?
Web 2
Idle
Web 3
Idle

Status: No Load Balancer. All traffic goes to Web 1.

Advanced: Rolling Updates and Service Restart Policies

Compose does not perform rolling updates (updating containers one by one to avoid downtime). When you change a service's image or configuration and run docker compose up, Compose's default behavior is to recreate all containers for that service simultaneously.

Visualizing Simultaneous Recreate

The Behavior: When you deploy a new version, Compose stops the old containers and starts the new ones at the same time. This causes a brief outage.

Web Service (v1) Running
Web Service (v1) Running

Notice: Both containers go down at the same time.

docker-compose.yml
# 1. The Service Definition
web:
  image: my-app:v2
  
  # 2. The "Restart" Policy (Crash Recovery)
  restart: unless-stopped  # ← Policy for *failure* recovery, not updates

Practical takeaway: In a single-host production setup with Compose, expect a brief service interruption during docker compose up after a code change. To minimize this, ensure your app handles SIGTERM gracefully and use a reverse proxy with health checks.

Real-world docker compose example: full stack application

Imagine a busy restaurant. You have the Customer (Frontend), the Waiter (API), the Pantry (Database), and the Prep Station (Cache).

In a real-world application, these aren't just separate people; they are separate containers. They need to talk to each other efficiently.

Your docker-compose.yml is the floor plan. It tells the Waiter exactly where the Pantry is located without giving them a phone number (IP address). Instead, you just say, "Go find the Pantry."

The key insight: **Services communicate using their *service names* as hostnames.** You never hardcode IPs.

The Networking Map: Host vs. Container

Professor's Warning: Beginners often get confused about "Localhost". Inside a container, localhost is the container itself, not your computer or the database.

Your Laptop (Host)
Docker Network
API (Node.js) Port 3000
DB (Postgres) Port 5432

The API needs to connect to the Database. Which address should it use?

Result: Waiting for input...

The Full Stack Blueprint

Here is how we define the "Restaurant" in code. Notice how the api service uses the db service name in its environment variables.

docker-compose.yml
# 1. The Frontend (Customer)
frontend:
  image: my-react-app
  ports:
    - "3000:80"  # Browser talks to Host Port 3000

# 2. The API (Waiter)
api:
  build: ./api
  ports:
    - "5000:3000"
  environment:
    DATABASE_URL: postgres://db:5432/mydb  # ✅ Uses service name 'db'
    REDIS_URL: redis://cache:6379        # ✅ Uses service name 'cache'
  depends_on:
    db:
      condition: service_healthy # Wait until DB is ready
    cache:
      condition: service_started

# 3. The Database (Pantry)
db:
  image: postgres:15
  volumes:
    - postgres_data:/var/lib/postgresql/data
  environment:
    POSTGRES_PASSWORD: ${POSTGRES_PASSWORD} # Secret from .env
  healthcheck:
    test: ["CMD-SHELL", "pg_isready -U postgres"]
    interval: 10s

# 4. The Cache (Prep Station)
cache:
  image: redis:7-alpine

# 5. Persistent Storage
volumes:
  postgres_data:

Advanced: The Secrets Vault

The Problem: You cannot put passwords in the YAML file (git commit risk) or even in the .env file (accidental commit risk).

Hardcoded ❌ Risky
.env File ⚠️ Better
Bind Mount ✅ Secure

Click the options to see how secrets are handled in production.

Current Status: Choose an option

Frequently Asked Questions (FAQ)

1. What is the difference between Docker Compose and Docker Swarm?

Think of Docker Compose as a project manager for a single building. It handles all the apartments (containers) on one floor (host machine).
Docker Swarm is a city planner. It manages an entire city of buildings (multiple servers/hosts).

C

Docker Compose

  • Scope: Single Host (Your Laptop/One VM)
  • File: docker-compose.yml
  • Best For: Development, Testing, Simple Production
S

Docker Swarm

  • Scope: Cluster (Many Servers)
  • File: Same YAML (plus deploy keys)
  • Best For: High Availability, Large Scale Production

2. Why does docker compose up fail with "cannot connect to the Docker daemon"?

This is the most common "Day 1" error. It means your command line (the client) is trying to talk to the background service (the daemon), but the phone line is dead.

Diagnostic Checklist

1. Is Docker Desktop running? Checking...
2. Is your user in the docker group? Checking...
3. Is the socket file accessible? Checking...

3. Can I use Docker Compose for production deployments?

Yes, but with boundaries. It is perfectly fine for a single server (VM). If you need to spread your app across 5 different servers, Compose cannot do that alone.

The "One Server" Rule

If your entire application (Frontend + Backend + DB) fits comfortably on one machine, Compose is a robust, stable choice for production. Just add restart: unless-stopped to your services to ensure they survive reboots.

4. How do I pass environment variables securely in a Docker Compose example?

Never hardcode secrets in your YAML. Use the Secure Bridge pattern: a .env file that Compose reads automatically.

Visualizing the Secure Bridge

Click the buttons to see how secrets are handled.

Select an option above to see the security risk.

5. Is Docker Compose suitable for microservices architecture?

Yes, for local development. It is the gold standard for running a microservices stack on your laptop. Each service gets its own container, and they talk via the private network.

However, for production microservices requiring auto-scaling and self-healing across many servers, you eventually migrate to Kubernetes. Compose is the training ground; Kubernetes is the stadium.

6. What are the performance limits of multi-container Docker with Compose?

The limit is your **hardware**. Compose itself adds almost zero overhead. The limit is how much RAM and CPU your single host has.

Visualizing Host Resource Limits

Click "Scale Up" to add more containers. Notice how the host CPU usage fills up. Once it hits 100%, the system slows down.

7. When should I avoid using Docker Compose in a DevOps pipeline?

Avoid Compose when your pipeline requires **multi-host deployment** or **rolling updates** (updating containers one by one without downtime).

Where Compose Fits in the Pipeline

Development
CI Testing
Single-Server Prod
Multi-Server Cluster

Compose is excellent for the first three stages. For the last one, switch to Kubernetes or Swarm.

8. How do I debug network connectivity issues between containers?

Treat it like a physical road. First, check if the containers are on the same network. Then, check if they can resolve each other's names (DNS).

Interactive Network Debugger

Scenario: The api service cannot connect to db.

Container: db Running
Container: api Idle

Notice: If you ping localhost, it will fail.

Use the service name db.

Post a Comment

Previous Post Next Post