在这里插入图片描述

本篇摘要

本文详解Docker Compose核心概念与用法,涵盖服务/项目定义、yml文件参数(如image/command/networks等)、常用命令(up/down/run等),通过图文演示环境搭建与配置技巧,助力快速掌握多容器应用编排。

一.Docker Compose(容器编排)

概念介绍

Docker Compose 是 Docker 官方的开源项目,使用 Python 编写而成;用于定义和编排(管理)多个 Docker 容器,从而运行复杂的应用。

关键概念

  • 服务 (Service):代表一个应用的容器,可以是由相同镜像创建的多个容器实例。
  • 项目 (Project):代表一个完整的业务单元,由一组关联的应用容器共同组成。

在这里插入图片描述

它通过一个名为 docker-compose.yml 的配置文件来定义项目和其中的所有服务;其默认的管理对象是整个项目,可以便捷地对项目内所有容器的生命周期(启动、停止、重建等)进行统一管理;能够轻松地定义和管理由多个相互依赖的服务(如 Web 应用、数据库、缓存等)组成的应用。

为啥需要Docker Compose

  • Docker 官方建议每个容器只运行一个进程(如应用、数据库、Nginx 各自独立);现代应用通常由多个服务组成,需要同时启动和管理多个容器。
  • 避免多次手动执行 docker run 命令或编写复杂脚本,提升效率。
  • 将分散的关联容器整合为一个整体项目,方便统一编排和管理。

Docker Compose 功能

  • 安装docker的时候默认安装了docker-compose-plugin组件。

  • 通过一个 docker-compose.yml 配置文件,定义多个相关联的服务,使它们能在隔离环境中协同运行;执行一条 docker compose up 命令,即可启动和运行整个多服务应用程序(比如哪个容器先启动哪个后启动)。

  • 提供命令来统一管理应用的生命周期,包括启动、停止和重新构建服务。

  • 可以方便地查看所有正在运行的服务的状态;能够实时流式传输(查看)所有服务的日志输出;支持在某个服务中运行一次性命令,便于调试或管理。

  • 默认每个docker-compose文件都创建自己对应的一个bridge网络,把对应的所有服务全部加入到对应的这个网络中,使得所有容器都能互相基于它进行通信。

Docker Compose 使用场景

  • 单主机快速部署:用于在单台机器上快速搭建和运行开发或测试环境,简单便捷。
  • 实现环境隔离:通过指定不同的项目(project)名称,可以在同一主机上隔离运行多个互不干扰的环境。

二.Docker Compose 文件(docker-compose.yml)解析

关于不同参数选项用法可以查阅对应文档:

点我查看对应document

在这里插入图片描述

yml文件基本使用格式:

  • 版本声明:文件开头通过 version 字段指定所使用的 Docker Compose 语法版本(如 “3.8”)。
  • 服务定义:核心部分是 services 块,用于定义多个应用容器(如 servicename, servicename2)。
  • 服务配置项:每个服务下可配置多个关键指令:
    • image: 指定服务所使用的镜像,为必填项。
    • command: 覆盖镜像中默认的启动命令。
    • environment: 设置容器内的环境变量。
    • volumes: 配置数据卷挂载,实现数据持久化或共享。
    • networks: 将服务连接到指定的自定义网络。
    • ports: 将容器端口映射到宿主机端口。
    • expose: 声明容器对外暴露的端口(不映射到宿主机)。
    • build: 指定构建镜像的上下文目录。
    • depends_on: 定义服务之间的启动依赖关系。
    • env_file: 从文件中批量读取环境变量。
  • 顶级资源定义:除了服务,还可以在顶层定义 volumesnetworks 等独立资源,供各服务使用。
  • 服务发现:服务名称(servicename)可作为容器间网络通信的内部 DNS 名称直接使用。

注意:

默认dockercompose以yml所在目录为项目目录;然后就是对应的yml缩进是空格格式不是Tab;缩进代表层级关系,必须使用空格(通常为2个空格)并且严格对齐​​

image选项

使用方法:

  1. 仅镜像名:使用官方镜像仓库中的镜像名称,如 image: redis
  2. 镜像名+标签:在名称后指定版本标签,如 image: redis:5
  3. 镜像摘要:使用唯一的哈希值(SHA256)精确锁定镜像版本,如 image: redis@sha256:0ed5...
  4. 仓库路径:指定镜像在仓库中的命名空间路径,如 image: library/redis
  5. 完整仓库地址:包含注册服务器地址的完整路径,如 image: docker.io/library/redis
  6. 私有仓库镜像:使用私有仓库地址及端口拉取镜像,如 image: my_private.registry:5000/redis

下面演示下:

首先创建对应项目目录:

在这里插入图片描述
在这里插入图片描述

  • 编辑好对应yml;这里其他选项不填就是默认(对应的服务名字就是项目-服务-第几个镜像形式呈现)。

在这里插入图片描述
在这里插入图片描述

  • 发现成功启动默认的nginx容器。

command选项

用于覆盖 Docker 容器镜像中设定的默认启动命令;在 Docker Compose 文件或 Dockerfile 中,通过 command 指令来定义新的启动命令。

两种写法

  • 列表格式:使用 JSON 数组形式,例如 command: ["bundle", "exec", "thin", "-p", "3000"]
  • 字符串格式:直接书写命令字符串,例如 command: bundle exec thin -p 3000

应用场景:常见于需要自定义服务启动参数的情况,例如为 Web 服务器指定运行端口、为应用传递特定环境变量等。

演示下:

在这里插入图片描述

在这里插入图片描述

  • 这里因为覆盖掉command的命令了,默认nginx就不是后台运行,所以运行下就停止了。

在这里插入图片描述

  • 查看容器详情Cmd被覆盖了。

3.entrypoint选项

entrypoint 指令用于覆盖 Docker 容器镜像中默认的启动入口点(也就是主命令)。

使用格式:

  • 格式一:执行脚本:可以指定一个可执行脚本的路径(如 entrypoint: /code/entrypoint.sh),作为容器启动时运行的入口程序。
  • 格式二:列表命令:也可以使用列表格式直接定义完整的命令及其参数(如 entrypoint: [ "php", "-d", "zend_extension=...", "-d", "memory_limit=-1", "vendor/bin/phpunit" ]),精确控制启动行为。
  • entrypointcommand 本身不会冲突,它们是组合关系,共同组合来执行命令。

应用场景:适用于需要自定义容器初始化流程或复杂命令参数的场景,例如设置特定扩展、配置运行参数后再启动主程序。

演示下:

在这里插入图片描述
在这里插入图片描述

  • 启动成功。

在这里插入图片描述

  • 查看容器详情发现对应的cmd为空,然后entrypoint就是这个要执行的命令,所以执行对应前台进程,保持nginx稳定运行不退出。

注意:
如果是后台进程的话,docker就会默认它启动完已经执行完了,立马让它exited状态,但是如果是前台进程,相当于占用控制台,一直在前台跑,docker就不会认为容器主进程已经执行完了,所以就不会让它直接退出;所以docker中的nginx默认启动就是前台进程,不会直接挂掉。

4.environment选项

用于在 Docker Compose 配置中为服务设置环境变量;支持映射(字典)和数组两种语法格式来定义变量;若值为布尔类型(如 true/false),必须用引号包裹,防止 YAML 解析器将其转换为 Python 的 True/False。

格式:

  1. 使用缩进的键值对形式,例如:
  • RACK_ENV: development
  • SHOW: "true"
  1. 数组语法示例:使用短横线列表形式,变量通过等号赋值,例如:
  • - RACK_ENV=development
  • - SHOW=true

演示下:

在这里插入图片描述
在这里插入图片描述

  • 运行成功,查看config也是没报错返回。

在这里插入图片描述

  • 环境变量也是被添加进入容器了。

5.networks选项

给容器分组,配置谁能和谁通信;隔离容器通信权限,实现分组管控。

用法 (在 docker-compose.yml 里)

services:
  web:                # 服务1
    image: nginx
    networks:
      - frontend       # 加入前端网络组
      - backend        # 同时加入后端网络组

  db:                  # 服务2
    image: mysql
    networks:
      - backend        # 仅加入后端网络组

networks:
  frontend:            # 网络组1(前端专用)
    driver: bridge     # 使用桥接模式(默认)
  backend:             # 网络组2(后端专用)
    driver: bridge

演示下:

在这里插入图片描述
在这里插入图片描述

在这里插入图片描述

  • 对应运行成功,容器网络也被添加。

6.volumes选项

把电脑上的文件夹或文件,映射到容器内部,实现数据同步和持久化。

  1. 简单写法

    volumes:
      - "电脑路径:容器路径"  # 冒号左边是电脑上的位置,右边是容器里的位置
    
  2. 复杂写法

    volumes:
      - type: volume      # 类型:volume (docker管理的卷) | bind (你电脑的路径)
        source: 来源名     # 卷名 或 电脑上的具体路径
        target: 容器路径   # 容器里出现的路径
volumes: # 表明主机的目录位置(比如命名卷)
  name:

核心就一点:电脑(源):容器(目标)

演示下:

在这里插入图片描述

在这里插入图片描述

  • 可以看到自动识别对的绑定卷。

在这里插入图片描述

  • compose运行成功。

在这里插入图片描述

  • 这里因为宿主机对应绑定目录是空给容器覆盖了。

在这里插入图片描述

  • 进行同步成功,对应html出现内容。

7.ports选项

1. 精细控制:

ports:
  - target: 80                # 容器内端口
    host_ip: 127.0.0.1        # 宿主机绑定IP(默认所有IP)
    published: 8080           # 宿主机映射端口
    protocol: tcp             # 协议类型(tcp/udp)
    mode: host                # 模式(host/ingress)

2.短语法格式:

ports:
  - "8000:8000"               # 主机端口:容器端口
  - "3000"                    # 随机主机端口→容器3000端口
  - "127.0.0.1:5000:5000"     # 指定IP映射
  - "6060:6060/udp"           # UDP协议映射
  - "9090-9091:8080-8081"     # 端口段批量映射

演示下:

在这里插入图片描述

在这里插入图片描述

  • 成功完成宿主机与主机映射。

8.expose选项

expose 用于声明容器内部监听的端口,仅允许同一网络下的其他容器访问,不会映射到宿主机 ;在服务配置下以列表形式声明内部端口号(支持字符串或数字格式)。

用法:

services:
  app:
    image: your-app
    expose:
      - "3000"    # 暴露3000端口(推荐字符串格式)
      - 8000      # 暴露8000端口(数字格式也可)

暴露的端口只能被同一 Docker 网络内的其他服务访问,外部主机和宿主机均无法直接访问;通常用于微服务间内部通信(如后端服务暴露API端口供前端服务内部调用)。

演示下:

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

  • 这里并没有完成主机与容器端口映射,只是说了下容器要暴露的是80端口。

9.build 选项

用于指定为构建镜像上下文路径。

services:
  服务名:
    build:
      context: .            # 必填:Dockerfile所在目录(`.`表示当前目录)
      dockerfile: Dockerfile # 可选:自定义Dockerfile文件名
      args:                 # 可选:构建时传递变量
        KEY: value

使用如

services:
  webapp:
    build: .               # 最短写法:直接指定上下文目录

  api:
    build:
      context: ./backend   # 指定子目录
      dockerfile: dev.Dockerfile  # 使用非标准文件名
      args:
        NODE_ENV: production

这里用法后面的dockerfile会用到。

10. depends_on 选项

depends_on 指令用于定义服务间的启动依赖顺序。为了让依赖控制更精确,可以配合 healthcheck 健康检查,确保不仅依赖服务已启动,而且其内部应用已准备就绪。

1. 基础依赖(仅控制启动顺序)

services:
  web:
    depends_on:
      - db     # 先启动db,再启动web
      - redis  # 先启动redis,再启动web

2. 高级依赖(等待服务就绪)
通过 condition: service_healthy 指定必须等待依赖服务通过健康检查后,才启动当前服务。这必须配合 healthcheck 配置使用

services:
  web:
    depends_on:
      db:
        condition: service_healthy  # 必须等待db服务健康

  db:
    image: mysql
    healthcheck:                    # 定义健康检查
      test: ["CMD", "mysqladmin", "ping", "-h", "localhost"] # 检查命令
      interval: 10s                # 每10秒检查一次
      timeout: 5s                  # 检查超时时间
      retries: 10                  # 失败重试次数

3. 健康检查 (healthcheck) 参数说明

  • test: 检查命令,如 ["CMD", "curl", "-f", "http://localhost"]
  • interval: 检查间隔(如 30s
  • timeout: 单次检查超时时间(如 5s
  • retries: 连续失败次数达到后标记为不健康

演示下:

在这里插入图片描述

在这里插入图片描述

  • 这里发现是先启动的mysql健康后,才启动的web服务(创建成功和启动成功不一样)。

在这里插入图片描述

  • 这里发现先先停止web才停止mysql;因为web依赖mysql运行。

11. env_file 选项

  1. 单一文件格式:使用 env_file 关键字直接指定一个环境变量文件路径(如 env_file: .env)。
  2. 列表格式:使用列表形式指定多个环境变量文件,按顺序加载(如 - ./common.env)。
  3. 路径类型:支持相对路径(如 ./common.env)和绝对路径(如 /opt/secrets.env)。
  4. 文件作用:将指定文件中的环境变量批量注入到容器中,避免在配置文件中硬编码。

演示下:

在这里插入图片描述
在这里插入图片描述

  • 成功运行成功,导入环境变量。

在这里插入图片描述
在这里插入图片描述

  • 两个文件的环境变量都被合并导入了。

三.docker compose 命令

命令清单

命令功能备注
docker compose build构建服务
docker compose config规范的格式来显示服务配置
docker compose cp在本地系统和服务容器直接拷贝文件
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命令会构建,(重新)创建,启动,链接一个服务相关的容器。默认情况下如果容器已经存在,将会停止并尝试重新创建他们。并使用之前挂载的卷。-no-recreate参数可以让容器不被停止或者重新创建,-d表示后台运行
docker compose version查看版本

详细可查看:官方文档

很多命令都和对应的docker的差不多,下面选择一些不一样的命令介绍。

docker compose 命令格式

1. 基本结构

docker compose [选项] 命令 [参数]

2. 最常用选项

  • -f:指定配置文件(默认用当前目录的 docker-compose.yml)
  • -p:给项目起个名(默认用当前文件夹名)

3. 使用示例

# 最简单的启动
docker compose up

# 指定配置文件和项目名
docker compose -f my-app.yml -p myproject up

# 后台启动
docker compose up -d

先写选项,再选命令,最后加参数!

演示下:

在这里插入图片描述

docker compose up命令

  1. 核心功能docker compose up 是核心启动命令,能自动完成构建镜像、创建服务、启动容器并关联依赖项的全流程。
  2. 后台运行:使用 -d 选项让容器在后台运行,这是生产环境的推荐用法。
  3. 容器重建控制
  • --force-recreate:强制重建容器(即使已存在)。
  • --no-recreate:若容器已存在则跳过重建(与上述选项互斥)。
  1. 服务选择:支持在命令末尾指定具体服务名(如 web db),仅启动部分服务。

演示下:

在这里插入图片描述

  • 容器已经存在,还强制创建新的进行覆盖。

在这里插入图片描述

  • 已经存在该些容器了,不再创建直接运行。

docker compose down命令

  1. 核心功能docker compose down 命令用于停止并删除docker compose up 创建的所有容器和网络。
  2. 基本语法:命令格式为 docker compose down [options] [SERVICE...],支持添加选项和指定部分服务。
  3. 关键选项 -v:使用 -v--volumes 选项可在删除容器的同时,删除其关联的所有命名卷和匿名卷(数据卷),实现彻底清理(只清理容器管理(docker管理的对应volumes下内容),不清理宿主机的内容)。
  4. 服务指定:可通过 [SERVICE...] 参数指定仅删除部分服务(如 docker compose down web db),而非全部服务。

演示下:

命名卷测试:

在这里插入图片描述

在这里插入图片描述

  • 命名卷启动,发现对应的内容同步过来了。

在这里插入图片描述

  • 没有-v,停止删除掉所有服务,发现对应内容还在。

在这里插入图片描述

  • 加上-v选项后,发现被docker管理的命名卷目录下的对应目录及内容就消失了。

绑定卷测试(Redis 服务没有定义任何卷挂载​​,但 Redis 官方镜像在 Dockerfile 中默认声明了数据卷,也就是说volume看到的卷是redis的匿名卷,而绑定卷是看不到的):

在这里插入图片描述
在这里插入图片描述

  • 首先进行运行起来。

在这里插入图片描述

  • 可以发现有四个匿名的匿名卷。

在这里插入图片描述

  • -v选项发现对应的卷还在。

下面再次重新启动下:

在这里插入图片描述

  • 发现对应的被创建成功。

在这里插入图片描述

  • 也位于对的docker管理volumes的路径下,有对应的标记。

在这里插入图片描述

  • 这里发现当-v后,对应的docker关于匿名卷的信息会删除(比如对应的docker对volume的管理标记,但是宿主机上之前映射内容还是会存在的(因为这是绑定卷,不受-v控制)。)

因此总结下:

docker compose down -v 只清理 Docker 自己管理的资源(容器、网络、命名卷 匿名卷等,对临时卷 绑定卷无效),而不会动宿主机上的任何文件(比如它不会删除对的绑定卷内容,而会删除对应的/var/lib/docker/volumes目录下内容,因为它是绑定卷,不受volume控制)。

docker compose run命令

  1. 命令功能:在指定服务的容器内执行一次性命令
  2. 基本格式docker compose run [选项] 服务名 [命令] [参数...]
  3. 常用选项
  • -d:让容器在后台运行。
  • --name:为本次运行的容器指定一个名字。
  • --entrypoint:覆盖容器默认的启动命令。
  • -e:设置环境变量(可多次使用)。
  • -u:指定运行命令的用户名或UID。
  • --rm:命令执行后自动删除容器。
  • -p:将容器端口映射到主机。

演示下:

在这里插入图片描述

在这里插入图片描述
在这里插入图片描述

  • 可以发现需要指定对应的服务名称而不是镜像,然后后面加上要在容器中执行对应的命令;这里发现容器执行完命令就退出来,因为后面执行的命令覆盖了默认的前台启动命令,docker就以为执行完了,就退出来了(这里必须换个yml;因为之前的那个yml的新的entrypoint把旧的(有sh可以接受对应输入命令)给覆盖了,不能执行所有输入的命令)。

文末配置代码汇总:

点我获取配置代码

四.本篇小结

通过学习本文可以知道Docker Compose是多容器应用的一站式管理工具,通过yml文件定义服务依赖与资源配置,结合up/down等命令实现高效编排,从开发到测试均可简化流程,是容器化部署的实用利器。

更多推荐