Review Questions - Container Orchestration & Compose#

Test your understanding of Docker Compose concepts with these review questions.


Multiple Choice#

1. How do services communicate with each other in Docker Compose by default?#

  • A) Via IP addresses only

  • B) Using service names as hostnames

  • C) Through localhost

  • D) They cannot communicate by default

Answer

B) Using service names as hostnames

Docker Compose creates a default network where services can reach each other using their service names as DNS hostnames. For example, a service named postgres can be reached at hostname postgres.


2. What does the depends_on directive do?#

  • A) Ensures services are on the same network

  • B) Controls the order in which services start

  • C) Shares volumes between services

  • D) Links environment variables between services

Answer

B) Controls the order in which services start

depends_on specifies that a service should wait for another service to start before starting itself. With conditions like service_healthy, it can also wait for health checks to pass.


3. What is the difference between ports and expose in docker-compose.yml?#

  • A) There is no difference

  • B) ports publishes to host, expose only exposes to other services in the network

  • C) expose publishes to host, ports only exposes to other services

  • D) ports is for TCP, expose is for UDP

Answer

B) ports publishes to host, expose only exposes to other services in the network

  • ports maps container ports to host ports, making them accessible from outside

  • expose only documents the port and makes it accessible to linked services, not the host


4. What happens to named volumes when you run docker compose down?#

  • A) They are always deleted

  • B) They are preserved unless you use -v flag

  • C) They are moved to a backup location

  • D) They are converted to bind mounts

Answer

B) They are preserved unless you use -v flag

Named volumes persist data even when containers are removed. To delete volumes along with containers, use docker compose down -v.


5. What file is automatically loaded with docker-compose.yml?#

  • A) docker-compose.local.yml

  • B) docker-compose.override.yml

  • C) docker-compose.dev.yml

  • D) docker-compose.default.yml

Answer

B) docker-compose.override.yml

Docker Compose automatically loads docker-compose.override.yml if it exists alongside docker-compose.yml. This is useful for development-specific configurations.


6. Which dependency condition waits for a service’s health check to pass?#

  • A) service_started

  • B) service_running

  • C) service_healthy

  • D) service_ready

Answer

C) service_healthy

depends_on:
  database:
    condition: service_healthy

This waits for the database service’s health check to pass before starting the dependent service.


7. How do you scale a service to 5 instances?#

  • A) docker compose scale service=5

  • B) docker compose up -d --scale service=5

  • C) docker compose replicas service 5

  • D) docker compose start service -n 5

Answer

B) docker compose up -d --scale service=5

The --scale flag allows you to run multiple instances of a service. Note that when scaling, you should use expose instead of fixed ports to avoid port conflicts.


8. What is the purpose of profiles in Docker Compose?#

  • A) To define security settings

  • B) To selectively start certain services

  • C) To configure logging

  • D) To set resource limits

Answer

B) To selectively start certain services

Profiles allow you to group services and only start them when that profile is activated:

services:
  debug-tools:
    profiles:
      - debug

Start with: docker compose --profile debug up


Scenario Questions#

9. Database Connection Refused#

Your application container keeps failing with “connection refused” when trying to connect to PostgreSQL, even though depends_on: [postgres] is configured.

What’s the likely issue and how do you fix it?

Answer

Issue: depends_on: [postgres] only waits for the container to start, not for PostgreSQL to be ready to accept connections.

Solution: Use health check condition:

services:
  app:
    depends_on:
      postgres:
        condition: service_healthy

  postgres:
    image: postgres:15
    healthcheck:
      test: ["CMD-SHELL", "pg_isready -U postgres"]
      interval: 5s
      timeout: 3s
      retries: 5

This ensures the app only starts after PostgreSQL is actually ready to accept connections.


10. Port Already in Use#

You try to start your compose stack but get an error saying port 5432 is already in use.

What are your options?

Answer

Options:

  1. Change the host port:

    ports:
      - "5433:5432" # Use 5433 on host, 5432 in container
    
  2. Stop the conflicting service:

    # Find what's using the port
    sudo lsof -i :5432
    # Stop local PostgreSQL
    sudo systemctl stop postgresql
    
  3. Don’t expose to host (if only needed internally):

    # Remove ports section, use expose instead
    expose:
      - "5432"
    
  4. Use a different project name to isolate networks:

    docker compose -p myproject up
    

11. Data Loss on Rebuild#

Every time you rebuild your containers, all database data is lost.

How do you fix this?

Answer

Issue: Data is stored inside the container instead of a persistent volume.

Solution: Use named volumes for database data:

services:
  postgres:
    image: postgres:15
    volumes:
      - postgres_data:/var/lib/postgresql/data

volumes:
  postgres_data: # Named volume - persists across rebuilds

Important notes:

  • Named volumes persist unless explicitly removed with docker compose down -v

  • Use docker volume ls to see existing volumes

  • Use docker volume inspect volume_name to see where data is stored


12. Environment Variables Not Working#

You set environment variables in .env file but they’re not being picked up by your application.

What could be wrong?

Answer

Possible issues and solutions:

  1. Not referencing .env file:

    services:
      app:
        env_file:
          - .env # Explicitly reference
    
  2. Variable substitution vs passing:

    # This substitutes at compose time (from shell or .env)
    environment:
      - DATABASE_URL=${DATABASE_URL}
    
    # This passes the file contents to the container
    env_file:
      - .env
    
  3. Wrong file name: Ensure it’s exactly .env not .env.txt

  4. Rebuild required:

    docker compose up -d --build
    
  5. Check variable is set:

    docker compose exec app env | grep DATABASE_URL
    

Command Identification#

13. Match the command to its purpose:#

Command

Purpose

docker compose logs -f app

?

docker compose exec app bash

?

docker compose run --rm app pytest

?

docker compose config

?

Answer

Command

Purpose

docker compose logs -f app

Follow (stream) logs for the app service

docker compose exec app bash

Open interactive shell in running app container

docker compose run --rm app pytest

Run one-off command (pytest) and remove container after

docker compose config

Validate and view the merged compose configuration


14. What commands would you use to:#

  1. Rebuild images and start all services

  2. Stop all services but keep volumes

  3. View resource usage of all containers

  4. Run database migrations before starting app

Answer
# 1. Rebuild and start
docker compose up -d --build

# 2. Stop without removing volumes
docker compose down  # (default behavior preserves volumes)

# 3. View resource usage
docker compose top
# or
docker stats

# 4. Run migrations before app
docker compose run --rm app alembic upgrade head
docker compose up -d

Short Answer#

15. Explain the difference between bind mounts and named volumes#

Answer

Bind Mounts:

  • Map a host directory to container path

  • Format: ./host/path:/container/path

  • Managed by user on host filesystem

  • Good for: development (hot reload), config files

  • Example: ./src:/app/src

Named Volumes:

  • Managed by Docker

  • Format: volume_name:/container/path

  • Stored in Docker’s data directory

  • Persist until explicitly deleted

  • Good for: database data, persistent application data

  • Example: postgres_data:/var/lib/postgresql/data

volumes:
  - ./app:/app # Bind mount
  - db_data:/var/lib/postgresql/data # Named volume

16. How do you configure different environments (dev/staging/prod) with Docker Compose?#

Answer

Method 1: Override files

# docker-compose.yml (base)
# docker-compose.override.yml (dev - auto-loaded)
# docker-compose.prod.yml (production)

# Development (automatic override)
docker compose up

# Production (explicit files)
docker compose -f docker-compose.yml -f docker-compose.prod.yml up

Method 2: Environment files

# .env.dev, .env.prod
docker compose --env-file .env.prod up

Method 3: Profiles

services:
  debug-tools:
    profiles: [dev]
  monitoring:
    profiles: [prod]
docker compose --profile dev up

17. What happens when you scale a service that has a fixed port mapping?#

Answer

Problem: Port conflicts occur because you cannot bind the same host port to multiple containers.

# This will fail when scaled
ports:
  - "8000:8000"

Solutions:

  1. Use port ranges:

    ports:
      - "8000-8010:8000"
    
  2. Use expose only (internal access):

    expose:
      - "8000"
    
  3. Use a load balancer:

    nginx:
      ports:
        - "80:80"
    app:
      expose:
        - "8000"
      deploy:
        replicas: 3
    

18. What is the purpose of health checks in Docker Compose?#

Answer

Health checks serve multiple purposes:

  1. Dependency coordination: With condition: service_healthy, dependent services wait until the dependency is actually ready, not just started

  2. Container orchestration: Docker can restart unhealthy containers (with appropriate restart policy)

  3. Load balancer integration: Load balancers can route traffic only to healthy containers

  4. Monitoring: Easily identify service health with docker compose ps

Example:

services:
  postgres:
    healthcheck:
      test: ["CMD-SHELL", "pg_isready -U postgres"]
      interval: 10s
      timeout: 5s
      retries: 5
      start_period: 30s

States: starting → healthy/unhealthy


Self-Assessment Checklist#

Rate your confidence (1-5) on each skill:

Skill

Confidence

Writing docker-compose.yml files

Configuring multi-service applications

Setting up service dependencies

Managing volumes and data persistence

Environment configuration

Scaling services

Debugging compose issues

Production configuration

Scoring:

  • 35-40: Expert level - ready to orchestrate complex applications

  • 25-34: Proficient - comfortable with multi-service deployments

  • 15-24: Intermediate - practice more complex scenarios

  • Below 15: Beginner - review documentation and redo exercises