美文网首页开发辅助技术
附录4、Docker-compose 配置文件编写指南

附录4、Docker-compose 配置文件编写指南

作者: 悟尘80 | 来源:发表于2020-05-09 09:42 被阅读0次

    本文是《Docker必知必会系列》第十二篇,原文发布于个人博客:悟尘纪

    上一篇:Docker必知必会系列(附录3):Docker-compose 命令使用指南

    前言

    Compose 配置文件采用 YAML 格式,用于定义 services(服务), networks(网络)和 volumes(卷)。

    文件的默认路径为./docker-compose.yml。有多种版本格式——1、2、2.x 和3.x。 有关每个版本与Docker的兼容性、包含哪些内容以及如何升级的最新信息,请参阅官方文档: 关于版本和升级

    服务定义包含应用于该服务启动的每个容器的配置,就像将命令行参数传递给 docker run一样。同样,网络和卷定义类似于 docker network createdocker volume create

    docker run 一样,Dockerfile 中指定的选项,例如 CMDEXPOSEVOLUMEENV,在缺省情况下都是遵守的——不需要再次以 docker-compose 方式指定它们。

    您可以使用类似 Bash 的${VARIABLE}语法在配置值中使用环境变量 - 有关完整详细信息,请参见变量替换

    文件结构和示例

    这是一个投票应用程序的 Compose 文件示例:

    version: "3.8"
    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
        deploy:
          placement:
            constraints:
              - "node.role==manager"
    
      vote:
        image: dockersamples/examplevotingapp_vote:before
        ports:
          - "5000:80"
        networks:
          - frontend
        depends_on:
          - redis
        deploy:
          replicas: 2
          update_config:
            parallelism: 2
          restart_policy:
            condition: on-failure
    
      result:
        image: dockersamples/examplevotingapp_result:before
        ports:
          - "5001:80"
        networks:
          - backend
        depends_on:
          - db
        deploy:
          replicas: 1
          update_config:
            parallelism: 2
            delay: 10s
          restart_policy:
            condition: on-failure
    
      worker:
        image: dockersamples/examplevotingapp_worker
        networks:
          - frontend
          - backend
        deploy:
          mode: replicated
          replicas: 1
          labels: [APP=VOTING]
          restart_policy:
            condition: on-failure
            delay: 10s
            max_attempts: 3
            window: 120s
          placement:
            constraints:
              - "node.role==manager"
    
      visualizer:
        image: dockersamples/visualizer:stable
        ports:
          - "8080:8080"
        stop_grace_period: 1m30s
        volumes:
          - "/var/run/docker.sock:/var/run/docker.sock"
        deploy:
          placement:
            constraints:
              - "node.role==manager"
    
    networks:
      frontend:
      backend:
    
    volumes:
      db-data:
    

    配置指令

    build

    指定 Dockerfile 所在文件夹的路径,Compose 将会利用它自动构建镜像。如:

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

    context、dockerfile和args

    可以使用 context 指定文件夹路径(可以是包含 Dockerfile 的目录路径,也可以是 git 存储库的 url),使用 dockerfile 指定 Dockerfile 文件名,使用 argDockerfile中的变量赋值。如:

    version: '3.8'
    services:
    
      webapp:
        build:
          context: ./dir
          dockerfile: Dockerfile-alternate
          args:
            buildno: 1
    

    如果在 build 同时指定了 image,那么 Compose 会使用在 image 中指定的名字和标签来命名最终构建的镜像。如:

    build: ./dir
    image: webapp:tag
    

    这将从 ./dir构建,生成名为 webapp,标签为:tag 的镜像。

    cache_from

    可以使用 cache_from 指定构建镜像时使用的缓存:

    build:
      context: .
      cache_from:
        - alpine:latest
        - corp/web_app:3.14
    

    labels

    通过标签向生成的镜像添加元数据:

    build:
      context: .
      labels:
        com.example.description: "Accounting webapp"
        com.example.department: "Finance"
        com.example.label-with-empty-value: ""
    
    build:
      context: .
      labels:
        - "com.example.description=Accounting webapp"
        - "com.example.department=Finance"
        - "com.example.label-with-empty-value"
    

    network

    设置构建期间 run 指令要链接的网络:

    build:
      context: .
      network: host   # 可以设置为 none 禁用网络
    

    sim_size

    设置所构建容器的/dev/shm分区大小:

    build:
      context: .
      shm_size: '2gb'
    

    target

    按照在 Dockerfile 中定义的方式构建指定的阶段。 有关详细信息,请参阅 多阶段构建 文档。

    build:
      context: .
      target: prod
    

    cap_add, cap_drop

    添加或删除容器的内核能力:

    cap_add:
      - ALL  # 让容器拥有所有能力
    
    cap_drop:
      - NET_ADMIN  # 移除 NET_ADMIN 功能
      - SYS_ADMIN  # 移除 SYS_ADMIN 功能
    

    cgroup_parent

    指定父 cgroup 组,意味着将继承该组的资源限制,如:cgroup_parent: m-executor-abcd

    command

    覆盖容器启动后默认执行的命令。如:command: echo "hello world"

    configs

    使用configs 按服务授予对配置的访问权限。详细内容请查看 官方文档

    container_name

    指定容器名称。默认将会使用 项目名称_服务名称_序号 这样的格式。

    container_name: lixl-web-container
    

    注意: 指定容器名称后,该服务将无法进行扩展(scale),因为 Docker 不允许多个容器具有相同的名称。

    depends_on

    指定服务之间的依赖关系,以便按顺序启动服务。以下例子中会先启动 redis db 再启动 web

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

    注意:web 服务不会等待 redis db 「完全启动」之后才启动。如果需要等待服务准备就绪,请参阅控制启动顺序 获取有关此问题的更多信息以及解决该问题的策略。

    deploy

    仅用于 Swarm mode,详细内容请查看 官方文档

    devices

    指定设备映射关系。使用与 docker 客户端 --device 相同的选项格式:

    devices:
      - "/dev/ttyUSB0:/dev/ttyUSB0"
    

    dns

    自定义 DNS 服务器,可以是单个值或列表。

    dns: 8.8.8.8
    
    dns:
      - 8.8.8.8
      - 114.114.114.114
    

    dns_search

    配置 DNS 搜索域,可以是单个值或列表。

    dns_search: example.com
    
    dns_search:
      - dc1.example.com
      - dc2.example.com
    

    entrypoint

    重写默认入口点,如:entrypoint: ["php", "-d", "memory_limit=-1", "vendor/bin/phpunit"]

    env_file

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

    如果通过 docker-compose -f FILE 方式来指定了 Compose 文件,则 env_file 中变量的路径相对于文件所在目录。

    environment 声明的变量,会覆盖这些值。即使这些值为空或未定义。

    env_file: .env
    
    env_file:
      - ./common.env
      - ./apps/web.env
      - /opt/secrets.env
    

    env文件中每一行必须符合 VAL=VAL 格式,以 # 开头的行被视为注释,并被忽略。空行也会被忽略。

    # 设置环境
    PRCK_ENV=development
    

    environment

    设置环境变量。你可以使用数组或字典两种格式。任何布尔值(True、 False、 yes、 no)都需要用引号括起来,以确保 YML 解析器不会将它们转换为 True 或 False。

    只有名称的变量会自动解析为 Compose 运行主机上对应变量的值,可以用来防止泄露不必要的数据。

    environment:
      RACK_ENV: development
      SESSION_SECRET:
    
    environment:
      - RACK_ENV=development
      - SESSION_SECRET
    

    expose

    在不将端口发布到主机的情况下公开端口——它们只能被链接的服务访问。 只能指定内部端口。

    expose:
     - "3000"
     - "8000"
    

    external_links

    注意:不推荐使用,建议使用 networks 指令代替。

    链接到 docker-compose.yml 外部的容器,甚至并非 Compose 管理的外部容器。

    external_links:
     - redis_1
     - project_db_1:mysql
     - project_db_1:postgresql
    

    extra_hosts

    添加主机名映射,使用与 Docker 中的 --add-host 参数相同的值:

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

    会在启动后的服务容器的 /etc/hosts 文件中添加如下两条条目。

    162.242.195.82  somehost
    50.31.209.229   otherhost
    

    healthcheck

    通过命令检查容器是否健康运行。

    healthcheck:
      test: ["CMD", "curl", "-f", "http://localhost"]
      interval: 1m30s
      timeout: 10s
      retries: 3
      start_period: 40s
    

    test 必须是字符串或列表。 如果是一个列表,则第一个参数必须是 NONECMDCMD-shell。 如果它是一个字符串,那么它等价于指定 CMD-SHELL,然后指定该字符串。以下写法效果是一样的。

    # Hit the local web app
    test: ["CMD", "curl", "-f", "http://localhost"]
    
    test: ["CMD-SHELL", "curl -f http://localhost || exit 1"]
    
    test: curl -f https://localhost || exit 1
    

    要禁用镜像默认健康检查设置,可以使用 disable: true。 这相当于指定 test: ["NONE"]。

    image

    指定要从哪个镜像启动容器。如果镜像在本地不存在,也没有指定了 buildCompose 将会尝试拉取这个镜像。

    image: ubuntu
    image: example-registry.com:4000/postgresql
    image: a4bc65fd
    

    init

    在容器中运行一个 init,用于转发信号和回收进程。 将此选项设置为 true,以便为服务启用此特性。

    version: "3.8"
    services:
      web:
        image: alpine:latest
        init: true
    

    默认使用的 init 二进制文件是 Tini,并安装在守护进程主机上的 /usr/libexec/docker-init 中。 可以通过 init-path 配置选项将守护进程配置为使用自定义 init 二进制文件。

    labels

    为容器添加 Docker 元数据(metadata)信息。

    labels:
      com.example.description: "Accounting webapp"
      com.example.department: "Finance"
      com.example.label-with-empty-value: ""
    

    logging

    配置日志选项。

    logging:
      driver: syslog
      options:
        syslog-address: "tcp://192.168.0.42:123"
    

    驱动程序名称为服务的容器指定了一个日志驱动程序,与 docker 运行 ---log-driver 选项一样。

    driver: "json-file"  # 默认值
    driver: "syslog"
    driver: "none"
    

    只有 json-filejournald 驱动程序可以直接从 docker-compose updocker-compose logs 中获得日志。 使用其他驱动程序都不打印日志。

    可以使用 options 配置日志驱动的相关参数。与 docker run--log-opt 选项一样。如 json-file支持的:

    options:
      max-size: "200k"
      max-file: "10"
    

    network_mode

    设置网络模式。和 docker run--network 参数一样。

    network_mode: "bridge"
    network_mode: "host"
    network_mode: "none"
    network_mode: "service:[service name]"
    network_mode: "container:[container name/id]"
    

    networks

    配置容器连接的网络。

    services:
    
      some-service:
        networks:
         - some-network
         - other-network
    
    networks:
      some-network:
      other-network:
    

    aliases

    同一网络上的其他容器可以使用服务名称或这个别名连接到服务的一个容器。由于别名是网络范围的,同一个服务在不同的网络上可以有不同的别名。

    version: "3.8"
    
    services:
      web:
        image: "nginx:alpine"
        networks:
          - new
    
      worker:
        image: "my-worker-image:latest"
        networks:
          - legacy
    
      db:
        image: mysql
        networks:
          new:
            aliases:
              - database
          legacy:
            aliases:
              - mysql
    
    networks:
      new:
      legacy:
    

    在上面的示例中,提供了三个服务(webworkerdb)以及两个网络(newlegacy)。 db 服务在 new 网络上的主机名为 dbdatabase ,在 legacy 网络上主机名为 dbmysql

    pid

    将 PID 模式设置为 host ,将与主机系统共享进程命名空间。使用此标志启动的容器可以访问和操作宿主机名称空间中的其他容器,反之亦然。

    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"
      - "12400-12500:1240"
    

    当使用 HOST:CONTAINER 格式来映射端口时,如果使用的容器端口小于 60 并且没放到引号里,可能会得到错误结果,因为 YAML 会自动解析 xx:yy 这种数字格式为 60 进制。

    为避免出现这种问题,建议数字串都采用引号包括起来的字符串格式。

    secrets

    存储敏感数据,例如 mysql 服务密码。

    version: "3.8"
    services:
      redis:
        image: redis:latest
        deploy:
          replicas: 1
        secrets:
          - my_secret
          - my_other_secret
    secrets:
      my_secret:
        file: ./my_secret.txt
      my_other_secret:
        external: true
    

    以上示例授予redis服务对my_secretmy_other_secret秘密的访问权限。 my_secret的值设置为文件./my_secret.txt的内容,并将 my_other_secret定义为外部资源,这意味着它已经在Docker中定义,可以通过运行docker secret create 命令进行定义。如果外部机密不存在,则部署将失败并显示secret not found错误。

    security_opt

    指定容器模板标签(label)机制的默认属性(用户、角色、类型、级别等)。例如配置标签的用户名和角色名。

    security_opt:
      - label:user:USER
      - label:role:ROLE
    

    stop_grace_period

    指定 stop_signal 在发送 SIGKILL 之前,如果容器无法处理 SIGTERM(或已使用指定的任何停止信号)而试图停止容器的等待时间 。

    stop_grace_period: 1s
    stop_grace_period: 1m30s
    

    默认情况下,stop在发送 SIGKILL 之前等待10秒以退出容器。

    stop_signal

    设置替代信号来停止容器。在默认情况下使用的是 SIGTERM 停止容器。

    stop_signal: SIGUSR1
    

    sysctls

    配置容器内核参数。

    sysctls:
      net.core.somaxconn: 1024
      net.ipv4.tcp_syncookies: 0
    
    sysctls:
      - net.core.somaxconn=1024
      - net.ipv4.tcp_syncookies=0
    

    tmpfs

    挂载一个临时文件系统到容器。

    tmpfs: /run
    tmpfs:
      - /run
      - /tmp
    

    ulimits

    指定容器的 ulimits 限制值。

      ulimits:
        nproc: 65535
        nofile:
          soft: 20000
          hard: 40000
    

    volumes

    数据卷所挂载路径设置。可以设置为宿主机路径(HOST:CONTAINER)或者数据卷名称(VOLUME:CONTAINER),并且可以设置访问模式 (HOST:CONTAINER:ro)。

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

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

    如果路径为数据卷名称,必须在文件中配置数据卷。

    version: "3"
    
    services:
      my_sql:
        image: mysql:8.0
        volumes:
          - mysql_data:/var/lib/mysql
    
    volumes:
      mysql_data:
    

    其它指令

    此外,还有包括 domainname, hostname, ipc, mac_address, privileged, read_only, shm_size, restart, stdin_open, tty, user, working_dir 等指令,基本跟 docker run 中对应参数的功能一致。

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

    user: nginx
    

    指定容器中工作目录。

    working_dir: /code
    

    指定容器中搜索域名、主机名、mac 地址等。

    domainname: your_website.com
    hostname: test
    mac_address: 08-00-27-00-0C-0A
    

    允许容器中运行一些特权命令。

    privileged: true
    

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

    restart: always
    

    以只读模式挂载容器的 root 文件系统,意味着不能对容器内容进行修改。

    read_only: true
    

    打开标准输入,可以接受外部输入。

    stdin_open: true
    

    模拟一个伪终端。

    tty: true
    

    读取变量

    Compose 模板文件支持动态读取主机的系统环境变量和当前目录下的 .env 文件中的变量。

    例如,下面的 Compose 文件将从运行它的环境中读取变量 ${MONGO_VERSION} 的值,并写入执行的指令中。

    version: "3"
    services:
    
      db:
        image: "mongo:${MONGO_VERSION}"
    

    如果执行 MONGO_VERSION=3.2 docker-compose up 则会启动一个 mongo:3.2 镜像的容器。

    若当前目录存在 .env 文件,执行 docker-compose 命令时将从该文件中读取变量。

    在当前目录新建 .env 文件并写入以下内容。

    # 支持注释
    MONGO_VERSION=3.6
    

    执行 docker-compose up 则会启动一个 mongo:3.6 镜像的容器。

    参考

    相关文章

    写在最后

    至此,本系列文章已经阅读完成。

    获取最新内容,请访问我的个人博客:悟尘纪

    相关文章

      网友评论

        本文标题:附录4、Docker-compose 配置文件编写指南

        本文链接:https://www.haomeiwen.com/subject/beyhnhtx.html