Skip to content

懒猫微服开发篇(七): 解析 Docker Compose Override

看过很多的 Docker 教程,也都不曾提到过 compose override,第一次接触到这个是在懒猫微服上解开 LPK 看到的,用来注入 docker 引擎的环境变量。但是还以为是懒猫微服的小技巧,今天整理笔记才发现原来的 Docker compose 用来做多环境部署的配置文件,比如用来给开发和生产分别注入不同的环境变量和配置文件。

参考文档:Docker Compose Override - LazyCat Developer Guide

使用场景是这样,在实际开发中,通常我们需要分别为开发和生产环境配置不同的服务和环境变量。虽然可以为每个环境维护独立的 Compose 文件,Docker Compose 提供了一个非常有用的特性,可以将多个 Compose 文件结合使用,简化配置管理。

  • 基础配置文件:第一个 Compose 文件通常作为基础配置,后续的文件可以覆盖该基础文件中的配置。
  • 覆盖配置:每个额外的文件不仅可以覆盖基础文件中的已有配置,还可以添加新的配置。

默认情况下,Compose 会读取以下两个文件:

  • docker-compose.yml:基础配置文件
  • docker-compose.override.yml:覆盖文件

你还可以通过 -f 参数指定多个非默认的覆盖文件,Compose 会按顺序合并这些文件。

docker compose -f docker-compose.yml -f dev.override.yml up
  • docker-compose config:这是一个非常有用的命令,可以帮助你验证最终的配置文件,尤其是在使用多个 Compose 文件时。它显示了合并后的 Compose 配置,帮助你确保配置符合预期。

示例:Nginx 配置

docker-compose.yml

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

docker-compose.override.yml

yml
services:
  web:
    volumes:
      - ./dev:/usr/share/nginx/html # 使用本地开发文件夹覆盖默认卷
    environment:
      - DEBUG=true # 启用开发环境的调试模式

image-20250717205319123

在这个例子中,docker-compose.override.yml 覆盖了 docker-compose.yml 中的配置,添加了开发环境相关的文件挂载和环境变量设置。

image-20250717205507275

合并后的配置(查看通过 docker-compose config 命令生成的配置)

bash
name: "3"
services:
  web:
    environment:
      DEBUG: "true"
    image: nginx:latest
    networks:
      default: null
    ports:
      - mode: ingress
        target: 80
        published: "80"
        protocol: tcp
    volumes:
      - type: bind
        source: /Users/name/Desktop/dev
        target: /usr/share/nginx/html
        bind:
          create_host_path: true
networks:
  default:
    name: 3_default

可以看到,通过合并配置,开发环境的调试模式和本地文件夹挂载已经成功加入了配置。

懒猫应用的上的 compose override

针对一些 lpk 规范目前无法覆盖到的运行权限需求, 可以通过 compose override 机制来间接实现。

通过应用查看器可以看到,这是 Docker Compose 配置的一部分,用于定义容器中的 containly 服务,并映射 playground 的 docker 引擎。具体的配置说明如下:

  • services: 这是 Docker Compose 文件的顶级字段,定义了服务列表。containly 是定义的一个服务名称。
  • containly: 这是服务的名称。在此配置下,的服务名是 containly
  • volumes: 定义了容器与宿主机(本地)之间的文件夹共享和挂载。该部分的配置是映射一个本地目录到容器内部的目录。
    • bind: 使用绑定挂载的方式(bind mount),允许宿主机的文件或目录直接映射到容器内部。这里设置了 create_host_path: true,意思是如果宿主机上的 /data/playground 目录不存在,它会自动创建。
    • source: 宿主机的路径,映射为容器中的目录。这里指定了 /data/playground 作为源路径,意味着宿主机上的这个目录将被挂载到容器内。
    • target: 容器内的路径,即宿主机上的 source 目录映射到容器内部的 /lzcapp/run/playground 目录。容器内的应用可以访问这个目录。
    • type: 这里设置的是 bind,表示采用绑定挂载方式

image-20250717210507516

最后 highlight 下 WIKI 里的三句话:

  1. 确认最终生成的 lpk 中存在名为 compose.override.yml 的文件,并且内容是一个合法的 Compose 合并文件。
  2. 通过 SSH 进入 /data/system/pkgm/run/$appid 目录,确认该目录下是否存在 override.yml 文件。
  3. 使用 lzc-docker-compose config 命令查看最终合并后的配置,确保它符合预期。

子/data/system/pkgm/run/$appid 目录里,我的结果如下,供参考。

bash
docker compose config

name: xudeploycontainly
services:
  app:
....
- type: bind
        source: /data/playground
        target: /lzcapp/run/playground
        bind:
          create_host_path: true
...

(base) lzcbox-029c588e /data/system/pkgm/run/xu.deploy.containly # ls
compose.override.yml  docker-compose.yml  pkg
(base) lzcbox-029c588e /data/system/pkgm/run/xu.deploy.containly # cat compose.override.yml
services:
  containly:
    volumes:
      - bind:
          create_host_path: true
        source: /data/playground
        target: /lzcapp/run/playground
        type: bind
❤️喜欢