Skip to content

Docker - Compose

Docker Compose is a tool for defining and running multi-container Docker applications. With Compose, you use a YAML file (typically docker-compose.yml) to configure your application’s services, networks, and volumes. Then, with a single command, you can create and start all the services from your configuration.

Compose is ideal for development, testing, and staging environments, as well as simple production deployments. It simplifies the management of applications that consist of multiple interconnected containers (e.g., a web server, database, caching layer).

Docker Compose is included as part of Docker Desktop for Windows and macOS. No separate installation is needed.

For Linux, Compose V2 is installed as a plugin for the Docker CLI. If you followed the recommended Docker Engine installation for Linux (using docker-compose-plugin), it should already be installed.

To verify your installation and check the version, run:

docker compose version

Note: Older installations might use a standalone docker-compose command (with a hyphen). This tutorial uses the modern docker compose (space) syntax.

Let’s create a simple example application with a web service (using Nginx) and a database service (using MySQL).

Create a file named docker-compose.yml in your project directory:

version: '3.9' # Specify compose file version (optional for latest features)
services:
web:
image: nginx:stable-alpine
ports:
- "8080:80" # Map host port 8080 to container port 80
volumes:
- ./html:/usr/share/nginx/html:ro # Mount local html directory (read-only)
depends_on:
- db
networks:
- app-network
db:
image: mysql:8.0
environment:
MYSQL_ROOT_PASSWORD: examplepassword
MYSQL_DATABASE: myappdb
MYSQL_USER: myappuser
MYSQL_PASSWORD: myapppassword
volumes:
- db-data:/var/lib/mysql # Use a named volume for persistence
networks:
- app-network
networks:
app-network:
driver: bridge
volumes:
db-data: # Define the named volume

Explanation:

  • version: '3.9': Specifies the Compose file format version.
  • services:: Defines the containers that make up your application.
  • web: & db:: Names of your services.
  • image:: Specifies the Docker image for the service.
  • ports:: Maps ports between the host and the container (HOST:CONTAINER).
  • volumes:: Mounts paths or named volumes (HOST_PATH/VOLUME_NAME:CONTAINER_PATH). Here, ./html is bind-mounted for Nginx content, and a named volume db-data is used for MySQL persistence.
  • depends_on:: Specifies dependencies between services (ensures db starts before web, though doesn’t guarantee readiness).
  • environment:: Sets environment variables inside the container (used here for MySQL setup).
  • networks: (under service): Connects the service to specified networks.
  • networks: (top-level): Defines the networks used by the application (here, app-network using the default bridge driver).
  • volumes: (top-level): Defines named volumes used by the application (here, db-data).

You would also need to create a local ./html directory with some content (e.g., an index.html file) for the Nginx service.

Running the Application with Docker Compose

Section titled “Running the Application with Docker Compose”

Navigate to the directory containing your docker-compose.yml file in the terminal and use the following commands:

# Create and start containers in the background (-d)
docker compose up -d
# View the status of the services
docker compose ps
# View logs from all services (or specify a service)
docker compose logs
docker compose logs web
# Stop and remove containers, networks, volumes defined in the file
docker compose down
# Stop services without removing them
docker compose stop
# Start stopped services
docker compose start

With docker compose up -d, Compose will:

  • Pull the necessary images (nginx, mysql) if not present locally.
  • Create the app-network network.
  • Create the db-data volume.
  • Create and start the db and web containers, connecting them to the network and setting up volumes/ports.

You should then be able to access the Nginx server at http://localhost:8080. The web service can connect to the database using the hostname db.