一文搞懂docker-compose.yml基本结构

1.什么是 Docker Compose ?

一个完整的项目是需要多个服务的,比如一个 Web 应用程序,它需要 MySQLRedisNginx 等服务。那么我们需要分别为应用、数据库和 nginx 创建单独的 docker 容器,然后分别启动容器。构建好 Docker 之后,每次启动应用,都至少需要 docker run 三次,这样会比较繁琐;另外,这些 docker 容器都是分散独立的,也不方便镜像管理。这就引出了 docker compose 来解决这类型的问题。

Docker Compose 使用 YAML 文件来配置应用程序的服务,包括容器映像、容器之间的网络连接、卷挂载以及其他运行时配置选项,它面向的是整个应用程序。

Compose file version 3 reference | Docker Docs

2.docker-compose.yml 基本结构

配置文件的主要结构如下:

version: "3.8" # 定义版本, 表示当前使用的 docker-compose 语法的版本
services: # 服务,可以存在多个
    servicename: # 服务名字,它也是内部 bridge 网络可以使用的 DNS name,如果不是集群模式相当于 docker run 的时候指定的一个名称,
   #集群(Swarm)模式是多个容器的逻辑抽象
        image: # 必选,镜像的名字
        command: # 可选,如果设置,则会覆盖默认镜像里的 CMD 命令
        environment: # 可选,等价于 docker container run 里的 --env 选项设置环境变量
        volumes: # 可选,等价于 docker container run 里的 -v 选项 绑定数据卷
        networks: # 可选,等价于 docker container run 里的 --network 选项指定网络
        ports: # 可选,等价于 docker container run 里的 -p 选项指定端口映射
        expose: # 可选,指定容器暴露的端口
        build: #构建目录
        depends_on: #服务依赖配置
        env_file: #环境变量文件
    servicename2:
  	image:
  	command:
  	networks:
    	ports:
    servicename3:
    #...
volumes: # 可选,等价于 docker volume create
networks: # 可选,等价于 docker network create

更多官网字段可以参考:Compose file version 3 reference | Docker Docs

2.1 image

  • 指定容器运行的镜像
# 下面的格式都可以
image: redis
image: redis:5
image: redis@sha256:0ed5d5928d4737458944eb604cc8509e245c3e19d02ad83935398bc4b991aac7
# 自己的仓库/镜像
image: library/redis 
image: docker.io/library/redis
image: my_private.registry:5000/redis

  1. 创建一个yml配置文件
  2. 写入如下内容
version: '3.8'
services:
  # web 是一个自己取名称
  web:
    # 镜像
    image: nginx:1.24.0
  1. 执行docker compose up -d

2.2 command

覆盖容器启动的默认命令

command: ["bundle", "exec", "rails", "server", "-p", "3000"]
# 或
command: bundle exec rails server -p 3000

command 字段用于指定容器启动时要执行的命令。

使用 docker inspectprj1-web-1

结果中 Cmd 配置告诉 Docker 在启动 Nginx 容器时执行 nginx -g "daemon off;" 这个命令,这样 Nginx 将在容器中以前台方式运行而不是作为守护进程。这就是容器启动的默认命令,修改command就可以修改启动命令。

2.3 entrypoint

entrypoint 用于设置容器启动时要执行的默认命令或脚本。与 cmd 不同,entrypoint 用于指定容器启动时的主要命令,而 cmd 则提供额外的默认参数。

entrypoint: /code/entrypoint.sh

我们查看prj1-web-1的详细信息:

entrypoint 配置信息。它告诉 Docker 在启动容器时执行 /docker-entrypoint.sh 脚本。

2.4 environment

添加环境变量。

# 例如:设置 MySQL 的密码
environment:
	-  MYSQL_ROOT_PASSWORD=123456
# 或
environment:
    MYSQL_ROOT_PASSWORD: 123456

布尔值需要用引号引起来,以确保 YML 解析器不会将其转换为 True 或 False

2.5 networks

指定容器运行的网络。

version: '3.8'
services:
  # web 是一个自己取名称
  web:
    # 镜像
    image: nginx:1.24.0
    # 加入指定网络
    networks:
      - mynetwork1
      - mynetwork2
# 创建两个网络
networks:
  mynetwork1:
  mynetwork2:

2.6 volumes

将主机的数据卷或者文件挂载到容器里。

version: '3.8'
services:
  # web 是一个自己取名称
  web:
    # 镜像
    image: nginx:1.24.0
    # 卷的配置
    volumes:
      # 命名卷
      - type: volume
        source: db-data
        target: /data
      # 绑定卷
      - type: bind
        source: /root/data # 宿主机
        target: /data # 容器
# 创建一个卷
volumes:
  db-data:

也可以如下格式:

volumes:
    - "db-data:/data"
    - "/root/data:/data"

2.7 ports

ports:
  - target: 80
    host_ip: 0.0.0.0
    published: 8080
  - target: 80
    host_ip: 127.0.0.1
    published: 8000-9000

第一个端口映射:

  • target: 80:容器内部的目标端口是 80
  • host_ip: 0.0.0.0:宿主机的 IP 地址是 0.0.0.0,表示监听所有网络接口。
  • published: 8080:将容器的端口 80 映射到宿主机的端口 8080

第二个端口映射:

  • target: 80:容器内部的目标端口是 80
  • host_ip: 127.0.0.1:只有在本地主机(即宿主机)上使用该地址(127.0.0.1)才能访问容器提供的服务。
  • published: 8000-9000:将容器的端口 80 映射到宿主机的端口范围 8000-9000

2.8 expose

暴露端口,但不映射到宿主机,只被连接的服务访问。

expose:
    - "3000"
    - "8000"

2.9 depends_on

version: "3.7"
services:
  # 服务1
  web:
  	# 依赖 db、redis 服务
    depends_on: 
      - db
      - redis
  # 服务2
  redis:
    image: redis
  # 服务3
  db:
    image: mysql

web 服务依赖于 dbredis 服务,所以在启动 web 服务之前, Docker Compose 会等待 dbredis 服务处于启动状态。

version: "3.8"

services:
  web:
    image: nginx:1.24.0
    environment:
      TEST: 1
    depends_on:
      mysql:
        condition: service_healthy
  mysql:
    image: mysql:5.7
    environment:
      MYSQL_ROOT_PASSWORD: "123456"
    healthcheck:
      test: mysql --user=root --password='123456' -e "SELECT 1;"
      interval: 10s
      timeout: 5s
      retries: 10
  • condition: service_healthy:指定了 web 服务只有在 mysql 服务处于健康状态时才会启动。
  • healthcheck:定义了健康检查的配置。
  • test:指定了检查 MySQL 是否能够成功连接和执行查询语句。
  • interval:指定了检查间隔为 10 秒。
  • timeout:指定了检查超时时间为 5 秒。
  • retries:指定了最大重试次数为 10 次。

3. Docker Compose 常见指令

更详细的命令:官网Overview of docker compose CLI | Docker Docs

命令功能
docker compose build构建服务
docker compose config规范的格式来显示服务配置
docker compose cp在本地系统和服务容器直接拷贝文件
docker compose create创建服务的容器
docker compose create创建服务的容器
docker compose down停止所有容器,并删除容器
docker compose events从服务器获取实时事件
docker compose exec在容器中执行命令
docker compose images列出所有容器使用的镜像
docker compose kill强制停止服务的容器
docker compose logs显示日志
docker compose ls显示所有项目
docker compose pause暂停服务
docker compose port列出所有的端口映射
docker compose ps该命令可以列出项目中目前的所有容器
docker compose pull拉取服务镜像
docker compose push推送服务镜像
docker compose restart重启或者重启某个服务
docker compose rm删除服务停止的容器
docker compose run在指定服务容器上执行相关的命令
docker compose start启动当前停止的某个容器
docker compose stop停止当前运行的某个容器
docker compose top显示运行的进程
docker compose unpause恢复服务
docker compose upup 命令会构建,(重新)创建,启动,链接一个服务相关的容器。
docker compose version查看版本

3.1 up 指令

  • 参数:
    -d 在后台运行服务容器。
    --force-recreate:强制重新创建容器,不能与 --no-recreate 同时使用。
    --no-recreate:如果容器已经存在了,则不重新创建,不能与 --force-recreate 同时使用。
    -f:指定使用的 Compose 模板文件,默认为 docker-compose.yml
    -p:指定项目名称,默认将使用所在目录名称作为项目名。
# 指定 config.txt 为模板文件,并且名称为 prj2
docker compose -f config.txt -p prj2 up -d

3.2 down 指令

  • 停止所有容器,并删除容器和网络。
docker compose down [options] [SERVICE...]
  • -v:删除容器同时删除目录映射。
docker compose down [options] [SERVICE...]
关于我
loading