「DOCKER-COMPOSE」- docker-compose.yaml

认识

官方文档

组成

—— 该部分将介绍 docker-compose.yaml 文件中的关键字,通常是语法相关的内容。

性质

针对我们的场景,所使用的 docker-compose 命令决定我们所使用 Compose File 的版本;

Q:如何确定 docker-compose 命令支持的 Compose File 版本?
A:现在 2025-10-20 The top-level version property is defined by the Compose Specification for backward compatibility. It is only informative and you’ll receive a warning message that it is obsolete if used.

服务启动

运行命令

docker-compose, run a script after container has started? – Stack Overflow

运行多行命令(多行脚本):

version: '3'

services:
  backend:
    ...
    entrypoint:
      - sh
      - -c
    command:
      - |
        while true
        do
            // do some stuff
        done

顺序启动(depends_on, condition, healthcheck, …)

depends_on, condition | https://docs.docker.com/compose/compose-file/05-services/#depends_on
healthcheck | https://docs.docker.com/compose/compose-file/05-services/#healthcheck

services:
  web:
    build: .
    depends_on:
      - db
      - redis
  redis:
    image: redis
  db:
    image: postgres

供 YAML 使用的环境变量

Environment variables in Compose | Docker Documentation

通过定义 .env 文件(或通过 docker-compose –env-file /path/to/envfile 参数),来指定环境变量文件的路径。

然后,我们便能够在 docker-compose.yaml 中使用这些环境变量:

version: '3'
services:
  web:
    image: "webapp:${TAG}"

注意事项:
1)引号问题:在 .env 中定义的环境变量,其 <VALUE> 不要使用引号(除非需要)。引号会被视为 <VALUE> 的成分;

资源限制(Resource Limits)

How to specify Memory & CPU limit in docker compose version 3 – Stack Overflow

version: "3.6"
services:
  example-container:
    deploy:
      # 资源限制
      resources:
        limits:
          cpus: '0.50'
          memory: 500M

针对 Compose file reference Version 3 配置,需要使用 –compatibility 选项启动服务:

docker-compose --compatibility up -d

日志轮转(Logging)

version: "3.6"
services:
  example-container:
    # 日志处理
    logging:
      driver: "json-file"
      options:
        max-size: "500M"
        max-file: "3"

指定用户 | User

How to configure docker-compose.yml to up a container as root – Stack Overflow

...
services:
    datapower:
        build: .
        user: root
        ports:
            - "9090:9090"
        depends_on:
            - db
...

转义字符

美元符号

escaping – How can I escape a $ dollar sign in a docker compose file? – Stack Overflow

在 docker-compose.yaml 中,通过 $$ 来表示 $ 符号,以防止被解析为变量;

存储数据 | volumes:

Volumes top-level element | https://docs.docker.com/reference/compose-file/volumes/

version: "3.9"

services:

  web:
    image: nginx:alpine
    volumes:
      - type: volume
        source: data-web
        target: /data
        volume:
          nocopy: true
      - type: bind
        source: ./static
        target: /opt/app/static
      - type: volume
        source: nfs-storage-foo
        target: /srv/nfs
        volume:
          nocopy: true

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

volumes:
  data-web:
  data-db:
  nfs-storage-foo:
    driver_opts:
      type: "nfs"
      o: "addr=10.40.0.199,nolock,soft,rw"
      device: ":/docker/example"

场景 | 挂载本地目录

Top-level volume with absolute path – Docker Engine / Compose – Docker Community Forums
docker volume create | Docker Docs

volumes:
  local-foo:
    driver: local
    driver_opts:
      device: ./
      o: bind
      type: local

网络配置 | networks:

Option network_mode: host in docker compose file not working as expected
Networking in Compose | Docker Docs

参考 Networking in Compose 文档,以获得关于 Docker Compose 的网络说明。

network_mode

Services top-level elements | Docker Docs

若未指定 network_mode 参数,则会为项目单独创建 Bridge 网络。

我们习惯指定 network_mode: “bridge” 以使用现有网络,防止 docker compose 创建更多网络以出现地址覆盖等问题。

.networks

通过 .networks 参数,能够配置多个网络,并将不同的 Container 关联到不同的网络。

通过 .networks.<name>.ipam 参数,能够进行网络地址的配置。

.services.<name>.networks

将 Container 关联到 .network 所定义的特定网络中。

构建

将 docker run 转化为 Docker Compose 文件:

应用

模板文件(docker-compose.yaml)

我们常用的 docker-compose.yaml 模板(直接复制):

version: '3'

services:
  backend:
    # 镜像配置
    image: ccr.ccs.tencentyun.com/d3rm-3rd/docker.io_library_ubuntu:24.04
    # 容器配置
    container_name: <container name>
    # 网络配置
    hostname: <hostname>
    network_mode: host
    ports:
      - "<host port>:<container port>"
    # 服务管理配置
    restart: always
    # 运行命令、及其环境信息
    volumes:
      - /etc/localtime:/etc/localtime
    environment:
      - <key>=<value>
    # 覆盖 ENTRYPOINT 参数
    entrypoint: /bin/entrypoint
    command: ["ls", "-l"]