Location>code7788 >text

Docker Compose

Popularity:118 ℃/2025-04-19 21:41:58

What is Docker Compose

Docker Compose is a orchestration and management tool for Docker, which allows you to use a YAML file to configure the service of your application. Through this file, you can define how multiple containers can be connected to each other through the network, and how to configure their environment variables, volume mounts, port mapping, etc. This makes running complex multi-container applications on a single host very simple and intuitive.
Docker Compose mainly solvesdocker runInstructions anddocker buildThe problem of running docker run manually afterwards.

Docker Compose main concepts

  • Services: In the Docker Compose file, a service usually refers to a container. You can define multiple services, each running one or more container instances. For example, your application might contain a web service and a database service.

  • Networks: Docker Compose creates and manages Docker networks so that services can communicate with each other. By default, Docker Compose creates a network for each service, but you can also define custom networks across multiple services.

  • Volumes: Volumes are a mechanism in Docker for persisting data. In Docker Compose, you can define volumes and mount volumes to specific paths within the container so that data is not lost even if the container is deleted.

  • Environment Variables: You can define environment variables for the service, which can be read and used inside the container. This is very useful for configuring the settings of the application.

  • Dependencies: You can define the dependencies of the service in the Docker Compose file to ensure that the service is started in the correct order. For example, you might want to start a database service first and then start a database-dependent service.

Install Docker Compose

Docker Compose project address:/docker/compose
Installation environment information

IP system Specification
10.0.0.10 Ubuntu22.04 2c4g

Preparation for installation: Docker is required

Installation steps:

# Download Docker Compose
 [root@lb ~]# wget /docker/compose/releases/download/v2.35.0/docker-compose-linux-x86_64
 [root@lb ~]# ll docker-compose-linux-x86_64
 -rw-r--r-- 1 root root 73664588 Apr 19 14:42 docker-compose-linux-x86_64

 # Move to /usr/bin/docker-compose
 [root@lb ~]# mv docker-compose-linux-x86_64 /usr/bin/docker-compose

 # Grant permissions
 [root@lb ~]# chmod +x /usr/bin/docker-compose
 [root@lb ~]# ll /usr/bin/docker-compose
 -rwxr-xr-x 1 root root 73664588 Apr 19 14:42 /usr/bin/docker-compose*

 # examine
 [root@lb ~]# docker-compose version
 Docker Compose version v2.35.0

Commonly used commands for Docker Compose

There are many commands in Docker Compose. Here are a few commonly used ones. If you encounter new commands later, you will continue to explain them.

Container related

  • docker-compose up -d: equivalent todocker run -d, create and run containers in the background
  • docker-compose ps: Check the container running status, only-qOptions
  • docker-compose down: delete containers, delete all contents of all containers (network, data volumes)
  • docker-compose start: start the container
  • docker-compose stop: container closes
  • docker-compose restart: restart the container
  • docker-compose top: view container process information
  • docker-compose logs: view container logs
  • docker-compose rm: delete container
  • docker-compose exec: Enter the container

Mirror related

  • docker-compose pull: pull the service's image
  • docker-compose push: push service image
  • docker-compose build: build service image

Common commands in Docker Compose files

Official website article:/reference/compose-file/services/
The Docker Compose file is a yaml file, and when running the docker-compose command, there must be a file in the directory where it is located.

services

The Compose file must set services to the top level element.servicesThe relevant information about specifying the running container can be understood asdocker runA collection of instructions
Example:

# docker-compose file
 [root@lb ~/services]# cat
 services:
   # Service Name
   web:
     image: nginx:latest
     Ports:
       - "8080:80"
	  
 # Run the container
 [root@lb ~/services]# docker-compose up -d
 [+] Running 1/1
  ✔ Container services-web-1 Started

 # View the running container
 [root@lb ~/services]# docker-compose ps
 NAME IMAGE COMMAND SERVICE CREATED STATUS PORTS
 services-web-1 nginx:latest "/docker-entrypoint...." web About a minute ago Up About a minute 0.0.0.0:8080->80/tcp, [::]:8080->80/tcp

image

Specify the basic image of the container runtime

ports

Specify the port number of the container when it is running, and multiple ports can be written

container_name

Specify the name of the container, nocontainer_nameWhen tagging, it willservices-[services_name]-[services_num]is the container name
Example:

[root@lb ~/container_name]# cat
 services:
   web:
     image: nginx:latest
     # Specify the container name
     container_name: nginx_1
     Ports:
       - "8081:80"
	  
 [root@lb ~/container_name]# docker-compose up -d
 [+] Running 2/2
  ✔ Network container_name_default Created 0.1s
  ✔ Container nginx_1 Started 0.2s
 [root@lb ~/container_name]# docker-compose ps -a
 NAME IMAGE COMMAND SERVICE CREATED STATUS PORTS
 nginx_1 nginx:latest "/docker-entrypoint...." web 5 seconds ago Up 5 seconds 0.0.0.0:8081->80/tcp, [::]:8081->80/tcp

build

Run Dockerfile, build the image to use, and have several subtitles

context

Specify the directory where the Dockerfile is located

dockerfile

Specify the file name of the Dockerfile, the same asdocker build -fDirective, this command can be written without writing, default is Dockerfile

Example:

[root@lb ~/build]# cat
 services:
   zrlog:
     container_name: zrlog
     # build command
     build:
       context: ./zrlog
       dockerfile: Dockerfile
     Ports:
       - "8082:8080"
	  
 # Build a mirror
 [root@lb ~/build]# docker-compose build
 Compose can now delegate builds to bake for better performance.
  To do so, set COMPOSE_BAKE=true.
 [+] Building 6.5s (9/9) FINISHED docker:default
  => [zrlog internal] load build definition from Dockerfile 0.0s
  => => transferring dockerfile: 409B 0.0s
  => [zrlog internal] load metadata for /library/tomcat:9.0.87-jdk8-corretto 6.3s
  => [zrlog internal] load .dockerignore 0.0s
  => => transferring context: 2B 0.0s
  => [zrlog internal] load build context 0.1s
  => => transferring context: 10.80MB 0.1s
  => [zrlog 1/3] FROM /library/tomcat:9.0.87-jdk8-corretto@sha256:6928733a4f4c15d61c45a14b0197fe9a160f49f6f13b1b0b06310561cb320ef0
  => => writing image sha256:0d6bbaa1db8bf9d30e976c17f2991aca20e6b6e070be646b85240e1ec0ffdc71 0.0s
  => => naming to /library/build-zrlog 0.0s
  => [zrlog] resolving provenance for metadata file 0.0s
 [+] Building 1/1
  ✔ zrlog Built 0.0s
 # Start the mirror
 [root@lb ~/build]# docker-compose up -d
 [+] Running 2/2
  ✔ Network build_default Created 0.1s
  ✔ Container build-zrlog-1 Started

 [root@lb ~/build]# docker-compose ps
 NAME IMAGE COMMAND SERVICE CREATED STATUS PORTS
 zrlog build-zrlog "run" zrlog About a minute ago Up About a minute (healthy) 0.0.0.0:8082->8080/tcp, [::]:8082->8080/tcp

environment

docker run -eOptions, specify the environment variable after the container is run

Example:

[root@lb ~/environment]# cat
 services:
   db:
     image: mysql:5.7
     container_name: mysql_db
     Ports:
       - "3306:3306"
     environment:
       # Specify the password of MySQL root
       - "MYSQL_ROOT_PASSWORD=root123"
       # Specify creating a zrlog database
       - "MYSQL_DATABASE=zrlog"
 # Run
 [root@lb ~/environment]# docker-compose up -d
 [+] Running 2/2
  ✔ Network environment_default Created 0.1s
  ✔ Container mysql_db Started

 # check
 [root@lb ~/environment]# docker-compose ps -a
 NAME IMAGE COMMAND SERVICE CREATED STATUS PORTS
 mysql_db mysql:5.7 "..." db 14 seconds ago Up 14 seconds 0.0.0.0:3306->3306/tcp, [::]:3306->3306/tcp, 33060/tcp

restart

Specify the restart method of the container, anddocker run --restartConsistent options
Restart method:

  • Always: Automatic restart
  • unless-stopped: Restart only when the container is closed and stopped
  • on-failure: Restart only when failure

Example:

services:
   db:
     # Specify the restart policy
     restart: always
     image: mysql:5.7
     container_name: mysql_db
     Ports:
       - "3306:3306"
     environment:
       # Specify the password of MySQL root
       - "MYSQL_ROOT_PASSWORD=root123"
       # Specify creating a zrlog database
       - "MYSQL_DATABASE=zrlog"

volumes

Official website article:/reference/compose-file/volumes/
The volumes directive has two functions in the Compose file. When used as a top-level element, volume will create a data volume. When used as a child element, it will mount the data volume for the container.

Example:

[root@lb ~/volumes]# cat
 services:
   db:
     # Specify the restart policy
     restart: always
     image: mysql:5.7
     container_name: mysql_db_1
     Ports:
       - "3307:3306"
     environment:
       # Specify the password of MySQL root
       - "MYSQL_ROOT_PASSWORD=root123"
       # Specify creating a zrlog database
       - "MYSQL_DATABASE=zrlog"
     Volumes:
       - mysql_data:/var/lib/mysql
	  
 # Create a data volume of mysql_data
 Volumes:
   mysql_data:
 # Start the container
 [root@lb ~/volumes]# docker-compose up -d
 [+] Running 1/1
  ✔ Container mysql_db_1 Started # Check 0.3s
 [root@lb ~/volumes]# docker-compose ps -a
 NAME IMAGE COMMAND SERVICE CREATED STATUS PORTS
 mysql_db_1 mysql:5.7 "..." db 4 seconds ago Up 4 seconds 33060/tcp, 0.0.0.0:3307->3306/tcp, [::]:3307->3306/tcp

 # Check the data volume
 [root@lb ~/volumes]# docker inspect mysql_data
 [
     {
         "CreatedAt": "2025-04-12T15:42:17+08:00",
         "Driver": "local",
         "Labels": null,
         "Mountpoint": "/var/lib/docker/volumes/mysql_data/_data",
         "Name": "mysql_data",
         "Options": null,
         "Scope": "local"
     }
 ]

When you need to mount to the native host, only the volumes of the secondary element can be used

Example:

services:
  web:
    image: nginx:latest
    volumes:
      - ./html:/usr/share/nginx/html

External storage volumes can be used

Example:

services:
   web:
     image: nginx:latest
     Volumes:
       - web_data:/usr/share/nginx/html
 Volumes:
   web_data:
   #external specifies that this volume already exists on the platform and its lifecycle is managed by lifecycle outside the application.  If the volume does not exist, Compose will not create the volume and return an error.
     external: true

healthcheck

healthcheckA health check mechanism used to define a service. With a health check, you can ensure that the container can run properly after startup and automatically restart or reschedule when the container is unavailable.

Its child elements are:

  • test: Commands that define health checks. It can be a command or a script.
  • interval: The interval between two health checks (default unit is seconds).
  • timeout: The timeout for a single health check.
  • retries: The number of retrys after a health check failed.
  • start_period: The delay time for the health check to start after the container is started.
    Example:
services:
  web:
    image: nginx:latest
    ports:
      - "80:80"
    healthcheck:
      test: ["CMD", "curl", "-f", "http://localhost"]
      interval: 30s
      timeout: 10s
      retries: 3
      start_period: 5s

depends_on

depends_onUsed to control the startup order between services. It ensures that the service it depends on is started before starting a service. For example, web services rely on database services, and you can use depends_on when the database service is started first.

Althoughdepends_onEnsure the order of the service to start, but it will not wait for the service to be fully started before starting the dependent service. For example, the database service may still be in the initialization process, and the web service has been started, which may cause the web application to be unable to connect to the database service. At this time, it needs to be used.healthcheck

depends_onIt will only affect the start order of the container and will not affect the stop order of the container.
Example:

services:
   web:
     image: nginx:latest
     Ports:
       - "80:80"
     # Specify dependency on db service
     depends_on:
       db:
         condition: service_healthy
   db:
     image: mysql:latest
     environment:
       - "MYSQL_ROOT_PASSWORD=root123"
     # Health Check
     healthcheck:
       test: ["CMD", "mysqladmin", "ping", "-h", "localhost"]
       interval: 10s
       timeout: 5s
       retries: 5

links (it has been abandoned on Docker Compose version 3 or above)

linksIs a directive used to define the network connection between services. It allows one service to access the container of another service and communicate through the service name. Although links are very commonly used in earlier versions of Docker Compose, in Docker Compose version 3 and above,linksIt has been abandoned and it is recommended to use the default network function to enable communication between services.

What are links?

  • Establish a network connection: links is used to establish a network connection between services, allowing one service to access a container for another service.
  • Environment variables and /etc/hosts: When using links, Docker automatically sets the environment variables and /etc/hosts entries so that services can communicate through the service name.

Example:

[root@lb ~/links]# cat
 services:
   web1:
     container_name: nginx1
     image: nginx:latest
     links:
       - web2:nginx
     Ports:
       - "81:80"
   web2:
     container_name: nginx2
     image: nginx:latest
     Ports:
       - "82:80"

 # Run the container
 [root@lb ~/links]# docker-compose up -d
 [+] Running 3/3
  ✔ Network links_default Created 0.1s
  ✔ Container nginx2 Started 0.4s
  ✔ Container nginx1 Started 0.6s
 # examine
 [root@lb ~/links]# docker-compose ps -a
 NAME IMAGE COMMAND SERVICE CREATED STATUS PORTS
 nginx1 nginx:latest "/docker-entrypoint...." web1 13 seconds ago Up 11 seconds 0.0.0.0:81->80/tcp, [::]:81->80/tcp
 nginx2 nginx:latest "/docker-entrypoint...." web2 13 seconds ago Up 12 seconds 0.0.0.0:82->80/tcp, [::]:82->80/tcp


 ###### Test, enter the container inside nginx1
 [root@lb ~/links]# docker exec -it nginx1 bash
 # View hosts analysis
 root@12b2517e712e:/# cat /etc/hosts
 127.0.0.1 localhost
 ...
 # web2 hosts analysis
 172.24.0.3 12b2517e712e

 root@12b2517e712e:/# curl
 curl: try 'curl --help' or 'curl --manual' for more information
 root@12b2517e712e:/# curl http://nginx
 <!DOCTYPE html>
 <html>
 # Web page content
 </body>
 </html>

In Docker Compose version 3 and above, it is recommended to use the default network function to enable communication between services.

Example:

services:
  web1:
    container_name: nginx1
    image: nginx:latest
    ports:
      - "81:80"
  web2:
    container_name: nginx2
    image: nginx:latest
    ports:
      - "82:80"

In this example, web1 and web2 are connected to the same network by default, and web1 can directly access the web2 service through the web2 service name

networks

networksUsed to define and manage network communication between services, throughnetworksCustom networks can be created to connect services to these networks, enabling a flexible network structure.

In Docker Compose, if the network is not explicitly defined, Docker Compose automatically creates a default network for each project and connects all services to that network. The default network isBridge network(bridge network), services can communicate directly through the service name.

You can also customize networks and connect services to these networks, which can be bridges, hosts, or overlays.

Example:

services:
  web:
    image: nginx:latest
    ports:
      - "80:80"
    networks:
      - my_network
  db:
    image: mysql:latest
    environment:
      MYSQL_ROOT_PASSWORD: my-secret-pw
    networks:
      - my_network

networks:
  my_network:
    driver: bridge

deploy

deployConfiguration items are used to define the behavior of the service during deployment, including resource limits, number of replicas, update policy, restart policy, etc.
Here we take resource limitations as an example

services:
   web:
     image: nginx:latest
     Ports:
       - "80:80"
     deploy:
       resources:
         limits:
           cpus: '0.5' # Limit CPU usage to 0.5 cores
           memory: 50M # Limit memory usage to 50MB
         reservations:
           cpus: '0.2' # Reserved 0.2 cores
           memory: 20M # Reserved 20MB of memory

limits: defines the maximum amount of resources that a container can use.

  • cpus: floating point number, representing the number of CPU cores. For example, 0.5 means a limit to 0.5 cores.
  • memory: A string representing memory limit, which can be B (byte), K (kilobyte), M (megabyte), and G (gigabyte).

reservations: defines the amount of resources retained when the container starts.

  • cpus: floating point number, representing the number of CPU cores.
  • memory: a string, indicating the memory size.

Docker Compose variable file

Compose variable file is inCreated in a directory of the same level.envFile, in.envWrite to the filekey=valueThe form, then inIn the file${key}Use in the form of

Example:

[root@lb ~/var]# ll
 Total 16
 ## .env is a variable file
 -rw-r--r-- 1 root root 8 Apr 19 21:25 .env
 -rw-r--r-- 1 root root 73 Apr 19 21:26
 [root@lb ~/var]# cat .env
 PORT=83
 [root@lb ~/var]# cat
 services:
   web:
     image: nginx:latest
     Ports:
       ## ${PORT} value
       - "${PORT}:80"
 [root@lb ~/var]# docker-compose up -d
 [+] Running 2/2
  ✔ Network var_default Created 0.1s
  ✔ Container var-web-1 Started 0.4s
 [root@lb ~/var]# docker-compose ps
 NAME IMAGE COMMAND SERVICE CREATED STATUS PORTS
 var-web-1 nginx:latest "/docker-entrypoint...." web 7 seconds ago Up 6 seconds 0.0.0.0:83->80/tcp, [::]:83->80/tcp

Using multiple compose files

How should we run when we have multiple compose files?

Method 1: Use-fOptions for merge build

When there are multiple Docker Compose files, you can use the docker-compose command-fOptions to specify multiple Compose files and build and manage services together. This way allows you to split configurations into multiple files and then use them in combination.

For example, we have the following two compose files:

services:
  web:
    image: nginx:latest
    ports:
      - "80:80"

version: '3.8'
services:
  web:
    environment:
      - NGINX_ENV=prod
  db:
    image: mysql:latest
    environment:
      MYSQL_ROOT_PASSWORD: my-secret-pw

We can use the following command to build

docker-compose -f  -f  up -d

File merge rules:
Docker Compose loads the specified files in order and merges their contents. The merger rules are as follows:

  • Services: If the same service is defined in multiple files, the latter configuration overrides the former configuration.
  • Networks: If the same network is defined in multiple files, the latter configuration overrides the former configuration.
  • Volumes: If the same volume is defined in multiple files, the latter configuration overrides the former configuration.

We can use the docker-compose config command to view the merged configuration. This command will output the final configuration content to help you confirm whether the configuration is correct.

docker-compose -f  -f  config

Method 2: UseincludeElements to refer to other compose files

includeDirectives can refer to other Compose files in the main Compose file, thus enabling modularization and reuse of configurations. The referenced file can define services, networks, volumes, etc., and the main file will merge these contents into the final configuration.

Example:

include:
  -  
services:
  serviceA:
    build: .
    depends_on:
      - serviceB

It also supports loading Compose files from remote URLs

include:
  - /services/
  - /services/
services:
  serviceA:
    build: .
    depends_on:
      - serviceB

File merge rules

  • Docker Compose loads the files specified in include in order and merges their contents into the main file. The merger rules are as follows:
  • Services: If the same service is defined in multiple files, the latter configuration overrides the former configuration.
  • Networks: If the same network is defined in multiple files, the latter configuration overrides the former configuration.
  • Volumes: If the same volume is defined in multiple files, the latter configuration overrides the former configuration.

Things to note

  • File order: The loading order of files in include is very important. The subsequently loaded file will overwrite the configuration in the previously loaded file.
  • Local priority: Docker Compose uses local files first if local and remote files have the same path or URL.