一、Docker Compose 简介

Docker Compose 是一种用于定义和多容器 Docker 应用程序的工具。通过一个 docker-compose.yml 文件,可以配置应用程序需要的所有服务(例如:Web 服务器、数据库、缓存等)并轻松管理他们。

Docker Compose 使用的三个步骤:

  • 使用 Dockerfile 定义应用程序的环境
  • 使用 docker-compose.yml 定义构成应用程序的服务,这样它们可以在隔离环境中一起运行
  • 最后,执行 docker-compose up 命令来启动并运行整个应用程序

二、docker-composse 常用命令

1、docker-compose up 命令

用法:

docker-compose up [options]

示例:

docker-compose up -d

功能:

  • 创建并启动服务(容器):如果服务尚未创建,docker-compose up -d 会根据 docker-compose.yml 文件中的定义创建并启动这些服务。
  • 后台运行:-d 参数表示 detached 模式,即以分离模式运行,服务会在后台运行,不会占用当前终端
  • 重新创建容器:如果服务已经存在且正在运行,docker-compose up -d 会先停止并删除现有的容器,然后重新创建并启动新的容器
  • 构建镜像:如果配置文件中制定了 build 指令,docker-compose up -d 会检查并验证 docker-compose.yml 文件中的配置

使用场景

  • 首次部署:当第一次部署服务时,使用 docker-compose up -d 可以确保所有服务都按照最新配置创建并启动
  • 更新服务:当你修改了 docker-compose.yml 文件中的配置或镜像,使用docker-compose up -d 可以确保这些更改生效
  • 确保最新状态:无论服务是否已经存在,docker-compose up -d 都会确保服务是最新的状态。

用于部署一个 Compose 应用

默认情况下该命令会读取名为 docker-compose.yml 或 docker-compose.yaml 的文件

当然用户也可以使用 -f 指定其他文件名。通常情况下,会使用 -d 参数令应用在后台启动。

2、docker-compose down 命令

用法:

docker-compose down [options]

功能:

  • docker-compose down -v 命令用于停止并移除使用 docker-compose.yml 文件定义的所有容器、网络、卷(通过 -v 参数指定的数据卷)以及默认的网络桥接。
  • 使用 -v 参数会删除所有命名的数据卷。这可能会导致数据丢失,因此在执行前请确保已经做好了必要的备份。

使用场景:

  • 适用于彻底清理环境,例如在开发过程中需要重置环境或者测试不同配置时。
  • **完全重置环境:**当你需要完全重置开发环境,确保没有任何遗留数据时,可以使用 docker-compose down -v。
  • **测试环境清理:**在自动化测试中,每次测试结束后使用 docker-compose down -v 可以确保环境干净,不受上次测试的影响。
  • **部署前清理:**在部署新版本应用之前,使用 docker-compose down -v 可以确保没有旧版本的残留数据。

选项:

  • –rmi :删除镜像。type 可以是以下值之一:
    • all:删除所有服务的镜像。
    • local:仅删除那些不带有 :(表示镜像标签)或 latest 标签的镜像(通常是构建时创建的镜像)。
  • -v 或 --volumes:移除所有为服务定义的卷(包括默认卷和命名卷)。
  • –rmi-all:等同于 --rmi all,删除所有服务的镜像。
  • -h, --help:显示帮助信息。

示例:

  1. 停止并移除容器、网络和默认网络

    docker-compose down
    
  2. 停止并移除容器、网络、卷以及镜像

    docker-compose down --volumes --rmi all
    
  3. 仅移除构建时创建的本地镜像

    docker-compose down --rmi local
    
  4. 指定配置文件

    docker-compose -f my-compose-file.yml down
    

注意事项:

  • 使用 docker-compose down --volumes 会删除所有在 docker-compose.yml 文件中定义的卷,包括默认卷和命名卷。如果你不想删除这些卷,请不要使用这个选项。
  • 删除镜像操作是不可逆的,请确保在删除镜像之前备份必要的数据。
  • 如果你使用 Docker Compose 来管理多个环境(例如开发、测试和生产环境),请确保你在正确的环境中运行 docker-compose down 命令,以避免误删重要数据。

3、docker-compose stop 命令

docker-compose stop

停止 Compose 应用相关的所有容器,但不会删除它们。

被停止的应用可以很容易地通过 docker-compose restart 命令重新启动。

docker-compose stop 命令用于停止通过 docker-compose.yml 文件定义并启动的所有容器。这个命令不会移除容器、网络或卷,它只是停止了容器的运行。

4、docker-compose start 命令

docker-compose start

docker-compose start 命令用于启动之前已经创建但已停止的容器。

5、docker-compose restart 命令

docker-compose restart

重启已停止的 Compose 应用。

如果用户在停止该应用后对其进行了变更,那么变更的内容不会反映在重启后的应用中,这时需要重新部署应用使变更生效。

6、docker-compose ps 命令

docker-compose ps

用于列出 Compose 应用中的各个容器。

输出内容包括当前状态、容器运行的命令以及网络端口。

7、docker-compose rm 命令

用于删除已停止的 Compose 应用。它会删除容器和网络,但是不会删除卷和镜像。

语法:

docker-compose rm [OPTIONS] [SERVICE...]

选项:

  • **-f, --file FILE:**指定使用的 Compose 配置文件,默认为 docker-compose.yml。
  • **-v, --volumes:**删除容器的同时删除由 docker-compose.yml 文件定义的卷(如果它们存在并且是容器专用的)。
  • **-a, --all:**删除所有服务容器,而不仅仅是停止的容器。默认情况下,docker-compose rm 只删除停止的容器。
  • **–rmi TYPE:**删除镜像。这个选项会删除构建镜像时产生的中间镜像和构建缓存。TYPE 可以是 all(删除所有镜像)、local(只删除本地镜像)或 built(只删除通过 docker-compose 构建的镜像)。
  • **-s, --stop:**在删除容器之前先停止它们。这是默认行为,可以通过添加 --no-stop 标志来覆盖。
  • **–no-stop:**在删除容器之前不停止它们(通常与 -f 一起使用)

示例:

  1. 删除所有停止的容器

    docker-compose rm
    

    这个命令会删除所有在 docker-compose.yml 文件中定义且当前已停止的容器。

  2. 删除所有容器

    docker-compose rm -a
    

    这个命令会删除所有在 docker-compose.yml 文件中定义的容器,无论它们是运行中的还是已停止的。

  3. 删除容器和卷

    docker-compose rm -v
    

    这个命令会删除所有已停止的容器以及由 docker-compose.yml 文件定义的卷(如果它们存在并且是容器专用的)。

  4. 使用指定的 Compose 配置文件

    docker-compose -f my-compose.yml rm
    
  5. 这个命令会使用 my-compose.yml 文件来删除容器。

    docker-compose rm --rmi local
    

    这个命令会删除所有通过 docker-compose 构建且在本地存在的镜像。

    注意事项:

    • 使用 docker-compose rm 命令时,请确保你确实想要删除这些容器,因为删除后的数据(除非已备份到卷中)将不可恢复。
    • 如果容器正在运行,你需要先停止它们,或者使用 -s 或 --stop 选项来确保在删除之前先停止它们。

8、docker-compose logs 命令

docker-compose logs 命令用于查看 Docker Compose 应用中各个服务的日志。这个命令非常有用,因为它可以帮助你诊断问题或监视服务的行为。

基本用法:

docker-compose logs [options] [SERVICE...]

SERVICE(可选):指定要查看日志的服务名称。如果未指定,则显示所有服务的日志。

常用选项:

  • –follow, -f:实时跟踪日志输出,类似于 tail -f。
  • –tail, -t “all”:显示日志的最后几行。默认值是 all,也可以指定一个数字。
  • –no-color:禁用颜色输出,使日志更适合重定向到文件或其他工具。
  • –timestamps, -T:在日志输出中包含时间戳。

示例:

  1. 查看所有服务的日志

    docker-compose logs
    
  2. 查看特定服务的日志

    docker-compose logs web
    
  3. 查看特定服务的最后10行日志

    docker-compose logs --tail 10 web
    
  4. 查看所有服务的日志并包含时间戳

    docker-compose logs -T
    

9、使用多个Compose文件

你可以将配置拆分为多个文件:

docker-compose -f docker-compose.yml -f docker-compose.prod.yml up

三、docker-compose.yml 配置详解

1、Compose配置文件格式版本与Docker引擎的兼容性表

Compose file format Docker Engine release
Compose specification 19.03.0+
3.8 19.03.0+
3.7 18.06.0+
3.6 18.02.0+
3.5 17.12.0+
3.4 17.09.0+
3.3 17.06.0+
3.2 17.04.0+
3.1 1.13.1+
3.0 1.13.0+
2.4 17.12.0+
2.3 17.06.0+
2.2 1.13.0+
2.1 1.12.0+
2.0 1.10.0+

2、顶级配置项

  • version 定义了版本信息
  • services 定义了服务的配置信息
  • networks 定义了网络信息,提供给 services 中的 具体容器使用
  • volumes 定义了卷信息,提供给 services 中的 具体容器使用

示例:

version: "3.8" # Compose文件版本
services:
  redis: # 服务名称
    image: redis:alpine # 使用的镜像
    ports:
      - "6379" # 指定的端口
    networks:
      - frontend # 使用的网络
    deploy:
      replicas: 2
      update_config:
        parallelism: 2
        delay: 10s
      restart_policy:
        condition: on-failure

  db:
    image: postgres:9.4
    volumes:
      - db-data:/var/lib/postgresql/data
    networks:
      - backend

  result:
    image: nginx
    ports:
      - "5001:80"
    networks:
      - backend
    depends_on:
      - db
    deploy:
      replicas: 1
      update_config:
        parallelism: 2
        delay: 10s
      restart_policy:
        condition: on-failure

  worker:
    image: nginx
    networks:
      - frontend
      - backend
    deploy:
      mode: replicated
      replicas: 1
      labels: [APP=VOTING]
      restart_policy:
        condition: on-failure
        delay: 10s
        max_attempts: 3
        window: 120s

networks:
  frontend:
  backend:
volumes:
  db-data:

3、version 常用版本

指定Docker Compose文件格式的版本。常用版本为3.8,3.7等。

4、services 配置指令

  1. container_name

    指定自定义容器名称,而不是生成的默认名称。

    version: "3.8"
    services:
    
      redis:
        image: redis:alpine
        container_name: redis_test
    
  2. image

    指定容器运行的镜像名称或镜像 ID。如果镜像在本地不存在,Compose 将会尝试拉取这个镜像。

    version: "3.8"
    services:
    
      redis:
        image: redis:alpine
    
  3. build

    指定 Dockerfile 所在文件夹的路径(可以是绝对路径,或者相对 docker-compose.yml 文件的路径)。 Compose 将会利用它自动构建这个镜像,然后使用这个镜像。

    version: '3.8'
    services:
      webapp:
        build: ./dir
    

    也可以使用 context 指令指定 Dockerfile 所在文件夹的路径(或者是git仓库的URL)。同时使用 dockerfile 指令指定 Dockerfile 文件名。

    version: '3.8'
    services:
    
      webapp: #自定义发我名称 ,主要用查询
        build:
          context: ./dir
          dockerfile: Dockerfile-name
    

    注意:

    如果同时指定了 image和 build, image 不在具有单独使用它的意义,而是指定了目前要构建的镜像的名称。 也就是说 Compose 会使用 build 指令中指定的 Dockerfile 构建的镜像,之后构建的镜像名称使用 image 中指定的名字 webapp:tag命名。

  4. command

    使用 command 可以覆盖容器启动后默认执行的命令。

    # 写成shell形式
    command: bundle exec thin -p 3000
    
    # 写成Dockerfile中的exec格式
    command: [bundle, exec, thin, -p, 3000]
    
  5. depends_on

    设置依赖关系。解决容器的依赖、启动先后的问题。

    version: "3.8"
    services:
      web:
        build: .
        depends_on:
          - db
          - redis
      redis:
        image: redis
      db:
        image: postgres
    

    **注意:**web 服务不会等待 redis 和 db 完全启动 之后才启动。

  6. environment

    添加环境变量。您可以使用数组或字典、任何布尔值,布尔值需要用引号引起来,以确保 YML 解析器不会将其转换为 True 或 False。

    environment:
      RACK_ENV: development
      SHOW: 'true'
    

    如果变量名称或者值中用到 true|false,yes|no 等表达布尔含义的词汇,最好放到引号里,避免 YAML 自动解析某些内容为对应的布尔语义。这些特定词汇如下:

    y|Y|yes|Yes|YES|n|N|no|No|NO|true|True|TRUE|false|False|FALSE|on|On|ON|off|Off|OFF
    
  7. expose

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

    仅可以指定内部端口为参数:

    expose:
     - "3000"
     - "8000"
    
  8. ports

    映射端口信息。

    宿主机端口 : 容器端口 (即:HOST:CONTAINER) 的格式,或者仅仅指定容器的端口(宿主机将会随机选择端口)。

    ports:
     - "3000"
     - "3000-3005"
     - "8000:8000"
     - "9090-9091:8080-8081"
     - "49100:22"
     - "127.0.0.1:8001:8001"
     - "127.0.0.1:5000-5010:5000-5010"
     - "6060:6060/udp"
    

    **注意:**当使用 HOST:CONTAINER 格式来映射端口时,如果你使用的容器端口小于 60 并且没放到引号里,可能会得到错误结果,因为 YAML 会自动解析 xx:yy 这种数字格式为 60 进制。为避免出现这种问题,建议数字串都采用引号括起来的字符串格式。

  9. extra_hosts

    添加主机名映射。类似 docker client --add-host。

    extra_hosts:
     - "somehost:162.242.195.82"
     - "otherhost:50.31.209.229"
    

    以上会在此服务的内部容器中 /etc/hosts 创建一个具有 ip 地址和主机名的映射关系:

    162.242.195.82  somehost
    50.31.209.229   otherhost
    
  10. networks

    配置容器连接的网络,引用顶级 networks 下的条目 。

    services:
      some-service:
        networks:
          some-network:
            aliases:
             - alias1
          other-network:
            aliases:
             - alias2
    networks:
      some-network:
        # Use a custom driver
        driver: custom-driver-1
      other-network:
        # Use a custom driver which takes special options
        driver: custom-driver-2
    
  11. entrypoint

    指定服务容器启动后执行的入口文件。

  12. user

    指定容器中运行应用的用户名。

  13. working_dir

    指定容器中工作目录。

  14. restart

    restart:

    • no:是默认的重启策略,在任何情况下都不会重启容器。
    • always:容器总是重新启动。
    • on-failure:在容器非正常退出时(退出状态非0),才会重启容器。
    • unless-stopped:在容器退出时总是重启容器,但是不考虑在Docker守护进程启动时就已经停止了的容器
    restart: "no"
    restart: always
    restart: on-failure
    restart: unless-stopped
    

    指定容器退出后的重启策略为始终重启。该命令对保持服务始终运行十分有效,在生产环境 中推荐配置为 always 或者 unless-stopped 。

    restart: always
    

    注:swarm 集群模式,请改用 restart_policy。

  15. aliases

    **aliases :**同一网络上的其他容器可以使用服务名称或此别名来连接到对应容器的服务。

    services:
      some-service:
        networks:
          some-network:
            aliases:
             - alias1
             - alias3
          other-network:
            aliases:
             - alias2
    
  16. healthcheck

    用于检测 docker 服务是否健康运行。

    services:
      web:
        image: nginx
        healthcheck:
          test: ["CMD", "curl", "-f", "http://localhost"] # 设置检测程序
          interval: 1m30s # 设置检测间隔
          timeout: 10s # 设置检测超时时间
          retries: 3 # 设置重试次数
          start_period: 40s # 启动后,多少秒开始启动检测程序
    
  17. env_file

    从文件添加环境变量。可以是单个值或列表的多个值。

    env_file: .env
    

    也可以是列表格式:

    env_file:
      - ./common.env
      - ./apps/web.env
      - /opt/secrets.env
    
  18. Compose中的环境变量

    你可以使用.env文件设置docker-compose.yml中使用的变量:

    version: '3.8'
    services:
      web:
        image: nginx
        ports:
          - "${HOST_PORT}:80"
    

    .env文件:

    HOST_PORT=8080
    

5、volumes 配置指令

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

version: "3.8"
services:
  db:
    image: postgres:latest
    volumes:
      - "/localhost/postgres.sock:/var/run/postgres/postgres.sock"
      - "/localhost/data:/var/lib/postgresql/data"

数据卷所挂载路径设置。可以设置宿主机路径 (HOST:CONTAINER) 或加上访问模式 (HOST:CONTAINER:ro)。

该指令中路径支持相对路径:

volumes:
 - /var/lib/mysql
 - cache/:/tmp/cache
 - ~/configs:/etc/configs/:ro

6、networks 配置指令

  1. 未显式声明网络环境

    使用docker-compose up启动容器后,这些容器都会被加入app_default网络中。使用docker network ls可以查看网络列表,docker network inspect 可以查看对应网络的配置。

    version: '3'
    services:
      web:
        mage: nginx:latest
        container_name: web
        depends_on:
          - db
        ports:
          - "9090:80"
        links:
          - db
      db:
        image: mysql
        container_name: db
    
  2. networks关键字指定自定义网络

    例如:下面的docker-compose.yml文件,定义了front和back网络,实现了网络隔离。其中proxy和db之间只能通过app来实现通信。其中,custom-driver-1并不能直接使用,你应该替换为host, bridge, overlay等选项中的一种。

    version: '3.8'
    
    services:
      proxy:
        build: ./proxy
        networks:
          - front
      app:
        build: ./app
        networks:
          - front
          - back
      db:
        image: postgres
        networks:
          - back
    
    networks:
      front:
        # Use a custom driver
        driver: custom-driver-1
      back:
        # Use a custom driver which takes special options
        driver: custom-driver-2
        driver_opts:
          foo: "1"
          bar: "2"
    
  3. 配置默认网络

    version: '3.8'
    
    services:
      web:
        build: .
        ports:
          - "8000:8000"
      db:
        image: postgres
    
    networks:
      default:
        # Use a custom driver
        driver: custom-driver-1
    
  4. 使用已存在的网络

    networks:
      default:
        external:
          name: my-pre-existing-network
    

五、最佳实践

  • 保持docker-compose.yml简洁:使用多个文件来分离开发和生产配置。
  • 版本控制:将你的docker-compose.yml放入版本控制系统中,以管理跨环境的配置。
  • 使用命名卷:确保数据在容器重启后依然存在。
version: '3.8'  # 指定Compose文件的版本

services:  # 定义多个服务
  web:  # Web服务,通常是前端或后端的应用
    image: nginx:latest  # 使用Nginx镜像
    ports:
      - "80:80"  # 将容器的80端口映射到主机的80端口
    volumes:
      - ./web:/usr/share/nginx/html  # 挂载本地目录到容器中
    environment:
      - NGINX_HOST=localhost  # 设置环境变量
      - NGINX_PORT=80
    networks:
      - frontend  # 连接到前端网络
    depends_on:
      - app  # 该服务将在'app'服务启动后才启动
    restart: always  # 在容器崩溃后总是重启

  app:  # 应用服务,可以是任何语言的后端服务
    build:  # 从Dockerfile构建镜像
      context: ./app  # Dockerfile所在的目录
      dockerfile: Dockerfile  # 使用的Dockerfile名称
    ports:
      - "3000:3000"  # 将容器的3000端口映射到主机的3000端口
    volumes:
      - ./app:/usr/src/app  # 挂载本地代码目录到容器中
    environment:
      - NODE_ENV=development  # 设置环境变量
      - PORT=3000
    networks:
      - frontend  # 连接到前端网络
      - backend  # 连接到后端网络
    depends_on:
      - db  # 该服务将在'db'服务启动后才启动
    restart: on-failure  # 仅在容器非正常退出时重启

  db:  # 数据库服务,使用MySQL
    image: mysql:5.7  # 使用MySQL 5.7镜像
    volumes:
      - db_data:/var/lib/mysql  # 持久化MySQL数据到命名卷
    environment:
      MYSQL_ROOT_PASSWORD: example  # MySQL root用户的密码
      MYSQL_DATABASE: example_db  # 自动创建的数据库名称
      MYSQL_USER: user  # 创建的用户名称
      MYSQL_PASSWORD: password  # 用户密码
    networks:
      - backend  # 连接到后端网络
    restart: unless-stopped  # 仅在手动停止时不重启

volumes:  # 定义命名卷,用于数据持久化
  db_data:  # MySQL数据卷

networks:  # 定义自定义网络
  frontend:  # 前端网络,连接web和app服务
  backend:  # 后端网络,连接app和db服务
Logo

魔乐社区(Modelers.cn) 是一个中立、公益的人工智能社区,提供人工智能工具、模型、数据的托管、展示与应用协同服务,为人工智能开发及爱好者搭建开放的学习交流平台。社区通过理事会方式运作,由全产业链共同建设、共同运营、共同享有,推动国产AI生态繁荣发展。

更多推荐