Zhonghui

每个不曾起舞的日子,都是对生命的辜负

User Tools

Site Tools


软件:docker:docker_compose基础

Docker Compose基础

基础概念

docker-compose 设计用于 单机(单个 Docker 引擎)编排,不负责把同一套服务分布到多个物理结点上;它没有集群调度、跨节点网络、自动迁移/自愈等能力。要跨节点,就得用 Kubernetes

使用(同一个)Compose启动的容器们会被放到一个分组里面

配置文件

比如:compose.yaml(这个命名应该不是固定的吧)

  1. 结构:Project > Services > Container(s)
  2. Project 是用名字区分的
  3. 每个 service 可以理解为一个(或多个复制的)容器
  4. 一个 service 内部的容器,使用数字进行编号(比如xxx_1)
  5. 所以在一个compose项目内部的容器,基本上是这样的命名:<project>_<service>_container_name_<index>

常用命令

# 最常用的 compose 命令
# -f 指定配置文件
# up 表示启动 OR 更新
# -d 表示后台运行
docker compose -f docker-compose.yaml up -d

新版Compose命令

  1. docker-compose(连字符)= Compose v1:早期的独立二进制(Python 实现),自 2023 年 7 月起停止更新,并且在新的 Docker Desktop 里已不再提供
  2. docker compose(空格)= Compose v2:已集成到 Docker CLI 的插件(Go 实现)。这是当前推荐的用法与版本,持续有新特性与修复
  3. v2 基本可作为 v1 的“几乎即插即用替代”,大多数命令/参数一致;但少数命令在 v2 不再支持
  4. 容器命名规则有细微差异:v1 用下划线 [_],v2 用连字符 [-](上面提到的<project>_<service>_container_name_<index>?)
  5. 现在应优先使用 docker compose

对「更新」的理解

使用 docker compose 启动一个集群是很好理解的。但是实际上,在集群启动后,再编辑文件(比如修改一些参数),重新执行上述命令(和启动集群时用的命令一样),集群就会被更新(而不是创建一个新的集群出来)。难道是这份 yaml 文件和集群绑定了吗?并非如此,因为实际上把这份 yaml 文件复制到其他位置,还是可以一样使用。

实际上的工作原理是
docker compose启动一个集群的时候,集群会有一个名字。
如果再次执行compose up的时候,发现同一个名字的集群已经存在了,那么Docker就会尝试去更新它,而不是创建一个新的集群出来。
同理,如果执行compose up的时候,没有同名的集群(比如第一次执行,或者使用参数指定了新名字),那么Docker就会创建新的集群。

那么容器是如何更新的呢?(这个更新肯定是增量更新的,全量更新也太笨了)
前面我们提到compose集群内的每一个容器,都有一个名字(<project>_*<*service*>_c*ontainer_name_<index>)。那么根据这个名字,我们就能判断一个容器是:新加入的、被删除的、要更新的。

  1. 新加入的:集群中没有这个容器,但是新的 yaml 文件中写了这个容器,那就创建这个新容器即可。
  2. 被删除的:集群中正在运行的容器,但是在 yaml 文件中被删除了,为了安全Docker默认不会删除它,保持不动。
  3. 要更新的:集群中正在运行的容器,在 yaml 文件中也没有被删除,但是它的配置更改了(比如环境变量,端口之类的),那么Docker会删除现有的容器,使用新的配置重新创建它(这是重建(recreate),不是在线热更新;容器会短暂中断)。那么Docker是如何检测配置发生了变化的呢?在启动一个容器的时候,Docker会根据其配置计算一个 hash,下一次 compose up 的时候,再使用新的配置内容计算一次,如果 hash 值发生了变化,就说明配置有变动,容器需要更新。
  4. 保持不动的:根据上述内容,很容易看出,现有的容器,在更新后的 yaml 文件中被保留,配置也没有变,那么就相当于这个容器本身没有任何变化,无须任何更新操作。

Compose集群内部的网络和卷

# 在 compose 的 yaml 文件中,声明网络(network)和卷(volume)
# 这些网络和卷会被自动创建,并且作为 compose 内部的资源使用
# 命名上也会自动加上前缀,类似:project_name_cb_var
 
volumes:
  cb_var:
    # 空的
 
networks:
  cb_net:
    driver: bridge
 
# 使用方式
# 这里使用的参数值,都是指向 yaml 文件内部声明的网络和卷
# 如果一定要使用外部的资源,需要单独声明 external
couchbase:
  image: couchbase:community-7.6.2
  volumes:
    - cb_var:/opt/couchbase/var
  networks:
    - cb_net

Misc

# 好像是自动 pull compose.yaml 文件内需要的镜像?
docker compose pull
/var/www/DokuWikiStick/dokuwiki/data/pages/软件/docker/docker_compose基础.txt · Last modified: 2025/09/25 03:14 by zhonghui