20230318--Docker Compose配置文件详解

Docker Compose配置文件是Docker Compose的核心,用于定义服务、网络和数据卷。格式为YAML,默认路径为./docker-compose.yml,可以使用.yml或.yaml扩展名,目前Compose配置文件格式的最新版本为V3。


Docker Compose配置文件详解.png

一)version

Docker Compose版本主要有1, 2, 2.x, and 3.x,以下表格是docker-compose支持的docker版本。

Docker Compose file format Docker Engine release
3.8 19.03.0+
3.7 18.06.0+
3.6 18.02.0+
3.5 17.12.0+
3.4 17.09.0+
3.3 17.06.0+
3.2 17.04.0+
3.1 1.13.1+
3.0 1.13.0+
2.4 17.12.0+
2.3 17.06.0+
2.2 1.13.0+
2.1 1.12.0+
2.0 1.10.0+
# docker-compose version
docker-compose version 1.26.0, build d4451659
docker-py version: 4.2.1
CPython version: 3.7.7
OpenSSL version: OpenSSL 1.1.0l  10 Sep 2019

1.Version 2.x

通过YAML的根配置项version来指定,具体配置如version: '2'或version: '2.1'等。
必须在Compose配置文件根选项指定版本号,并且主版本数字为2,且所有服务必须在services配置项下声明。1.6.0+版本的Compose都支持V2,Docker Engine的版本需要1.10.0+版本。
支持数据卷和网络的配置。
默认情况下,每个容器都加入了应用范围的默认网络,并且可以在与服务名称相同的主机名下发现。很大程度上links不是必要的。
V2中加入了环境变量替换。

2.Version 3.x

最新版本,也是推荐使用版本,推出该版的目的是为了在Compose和Docker Engine的swarm模式之间形成交叉兼容。通过YAML的根配置项version来指定,具体配置如version: '3'或version: '3.1'等。

在指定Compose配置文件要使用的版本时,需同时指定主版本数字和次版本数字。如果未给定次版本数字,则默认使用0而不是最新版本,因此将不支持再更高版本中才加入的新功能。比如version: '3',使用的是3.0版本而不是目前最新的3.9版本

二)networks

通过顶层networks配置项可以指定要创建的网络。

# docker network inspect docker_redis_network
[
    {
        "Name": "docker_redis_network",
        "Id": "74f09926f4d034f2ae63ff1a46590d883562e711814a0dcce7e683284e407c31",
        "Created": "2023-03-13T09:50:44.80943824+08:00",
        "Scope": "local",
        "Driver": "bridge",
        "EnableIPv6": false,
        "IPAM": {
            "Driver": "default",
            "Options": null,
            "Config": [
                {
                    "Subnet": "172.21.0.0/16",
                    "Gateway": "172.21.0.1"
                }
            ]
        },
        "Internal": false,
        "Attachable": true,
        "Ingress": false,
        "ConfigFrom": {
            "Network": ""
        },
        "ConfigOnly": false,
        "Containers": {
            "91abfc78b2fecc20f5fe2fdfdd575b0b30b9a5e1a3ec8fb459a336fb287e9be7": {
                "Name": "docker_redis_1",
                "EndpointID": "812224986f60105aa06b201b47a4568a38379e2a07ae5f942c3fcb6125b8aa5a",
                "MacAddress": "02:42:ac:15:00:02",
                "IPv4Address": "172.21.0.2/16",
                "IPv6Address": ""
            }
        },
        "Options": {},
        "Labels": {
            "com.docker.compose.network": "redis_network",
            "com.docker.compose.project": "docker",
            "com.docker.compose.version": "1.26.0"
        }
    }
]

1.Name

为该网络设置一个自定义名称。

networks:
  network1:
    name: my-app-net

2.Driver

指定该网络所要使用的驱动。默认驱动取决于所使用的Docker Engine的配置方式,但是在大多数情况下,单个主机上用的bridge,Swarm上用的overlay。
docker网络模式主要有Host、Container、None、Bridge、overlay
Host:容器不会虚拟出自己的网卡、配置主机的IP,而是使用宿主机的IP和端口;
Container:创建的容器不会创建自己的网卡,配置自己的IP,而是和一个指定的容器共享IP、端口的范围;
None:该模式关闭了容器的网络功能;
Bridge:默认为该模式,桥接,此模式会为每一个容器分配,设置IP等,并将容器连接到虚拟网桥docker0,通过docker0 网桥以及iptables nat表配置与宿主机通信;
overlay:overlay驱动在一个swarm中的多个节点之间创建一个命名网络。

networks:
  network1:
    driver: overlay

3.EnableIPv6

在该网络上启用IPv6网络(如果要使用enable_ipv6配置项,则需要使用V2版Compose配置文件)。

4.IPAM

指定自定义IPAM配置。
有以下配置选项:
driver:自定义IPAM驱动以代替默认驱动。
config:包含零个或多个配置块的列表,每个配置块可以有以下配置选项。
subnet:设置表示网段的CIDR格式的子网。
gateway:设置表示网段的子网掩码。仅适用于V2版Compose配置文件

networks:
  network1:
    ipam:
      driver: default
      config:
        - subnet: 172.28.0.0/16

5.Internal

指定是否创建一个与外部隔离的overlay网络。默认情况下,Docker也会将桥接网络连接到它以提供外部连接。如果要创建一个与外部隔离的overlay网络,需将此配置项设置为true。

6.Attachable

指定是否允许除服务之外的独立容器连接到该网络。仅在driver设置为overlay时使用。如果设置为true,则除了服务之外的独立容器也可以连接到该网络。如果独立容器连接到了overlay网络,那它可以与那些也从其他Docker守护进程连接到overlay网络的服务和独立容器进行通信。

networks:
  mynet1:
    driver: overlay
    attachable: true

7.Options

以键值对的形式指定用来传递给该网络所使用的驱动的列表选项。这些选项取决于驱动,可以参考驱动程序文档。

 networks:
   mynet1:
     driver_opts:
       foo: "bar"
       baz: 1

8.Labels

将元数据以标签的形式添加到容器中。可以使用数组或字典两种格式。

networks:
  mynet1:
    labels:
      - "com.example.description=Financial transaction network"
      - "com.example.department=Finance"
      - "com.example.label-with-empty-value"

9.external

指定该网络是否是外部网络。如果设置为true,则指定该网络是在Compose外部创建的。由于docker-compose up不会尝试创建该网络,如果该网络不存在则会引发错误。在3.3及以下版本的Compose配置文件格式中,external配置项不能与包括driver、driver_opts、ipam和internal等在内的其他网络配置项同时使用,在3.4及以上版本中则没有此限制。

三)volumes

在services中可以声明并直接创建数据卷,但是从整体规划以及实现多个服务重用的需要,通过顶层volumes配置项定义数据卷更规范,并且顶层volumes配置项定义的数据卷可以使用命令行或API轻松进行检索和检查。

docker cli查看定义的数据卷
# docker volume inspect docker_redis_vol
[
    {
        "CreatedAt": "2023-03-13T09:50:45+08:00",
        "Driver": "local",
        "Labels": {
            "com.docker.compose.project": "docker",
            "com.docker.compose.version": "1.26.0",
            "com.docker.compose.volume": "redis_vol"
            "com.example.department": "IT/Ops",
            "com.example.description": "Database volume",
            "com.example.label-with-empty-value": ""
        },
        "Mountpoint": "/var/lib/docker/volumes/docker_redis_vol/_data",
        "Name": "docker_redis_vol",
        "Options": null,
        "Scope": "local"
    }
]

1.Driver

指定该数据卷所要使用的数据卷驱动。默认为Docker Engine中配置使用的无论哪种驱动,大多数情况下为local驱动。如果驱动不可用,则引擎会在docker-compose up尝试创建数据卷时返回一个错误。

volumes:
  redis_vol:
    driver: local

2.Labels

将元数据以标签的形式添加到容器中。可以使用数组或字典两种格式。

volumes:
  redis_vol:
    labels:
      - "com.example.description=Database volume"
      - "com.example.department=IT/Ops"
      - "com.example.label-with-empty-value"

3.Name

为该数据卷设置一个自定义名称。

volumes:
  redis_vol:
    name: my-app-data

4.Options

以键值对的形式指定用来传递给该数据卷所使用的数据卷驱动的列表选项。

挂在nfs文件目录/docker/example
volumes:
  redis_vol:
    driver_opts:
      type: "nfs"
      o: "addr=10.40.0.199,nolock,soft,rw"
      device: ":/docker/example"

5.external

指定该数据卷是否是外部数据卷。如果设置为true,则指定该数据卷是在Compose外部创建的。由于docker-compose up不会尝试创建该数据卷,如果该数据卷不存在则会引发错误。在3.3及以下版本的Compose配置文件格式中,external配置项不能与包括driver、driver_opts和labels在内的其他数据卷配置项同时使用,在3.4及以上版本中则没有此限制。

四)services

一个比较完整的docker service详细配置内容
# docker inspect bf76418f4ab6
[
    {
        "Id": "bf76418f4ab69dff5892b1f53adcddbb5add2b4ed7b610359c1405a4dc7ab980",
        "Created": "2023-03-16T23:29:10.470087985Z",
        "Path": "docker-entrypoint.sh",
        "Args": [
            "redis-server",
            "/etc/redis/redis.conf"
        ],
        "State": {
            "Status": "running",
            "Running": true,
            "Paused": false,
            "Restarting": false,
            "OOMKilled": false,
            "Dead": false,
            "Pid": 1858657,
            "ExitCode": 0,
            "Error": "",
            "StartedAt": "2023-03-16T23:29:11.643425486Z",
            "FinishedAt": "0001-01-01T00:00:00Z",
            "Health": {
                "Status": "unhealthy",
                "FailingStreak": 11,
                "Log": [
                    {
                        "Start": "2023-03-17T07:39:42.421770498+08:00",
                        "End": "2023-03-17T07:39:42.520933467+08:00",
                        "ExitCode": -1,
                        "Output": "OCI runtime exec failed: exec failed: unable to start container process: exec: \"curl\": executable file not found in $PATH: unknown"
                    },
                    {
                        "Start": "2023-03-17T07:41:12.527300168+08:00",
                        "End": "2023-03-17T07:41:12.618813081+08:00",
                        "ExitCode": -1,
                        "Output": "OCI runtime exec failed: exec failed: unable to start container process: exec: \"curl\": executable file not found in $PATH: unknown"
                    },
                    {
                        "Start": "2023-03-17T07:42:42.624743521+08:00",
                        "End": "2023-03-17T07:42:42.721798285+08:00",
                        "ExitCode": -1,
                        "Output": "OCI runtime exec failed: exec failed: unable to start container process: exec: \"curl\": executable file not found in $PATH: unknown"
                    },
                    {
                        "Start": "2023-03-17T07:44:12.725901737+08:00",
                        "End": "2023-03-17T07:44:12.800762299+08:00",
                        "ExitCode": -1,
                        "Output": "OCI runtime exec failed: exec failed: unable to start container process: exec: \"curl\": executable file not found in $PATH: unknown"
                    },
                    {
                        "Start": "2023-03-17T07:45:42.80707081+08:00",
                        "End": "2023-03-17T07:45:42.958008502+08:00",
                        "ExitCode": -1,
                        "Output": "OCI runtime exec failed: exec failed: unable to start container process: exec: \"curl\": executable file not found in $PATH: unknown"
                    }
                ]
            }
        },
        "Image": "sha256:7614ae9453d1d87e740a2056257a6de7135c84037c367e1fffa92ae922784631",
        "ResolvConfPath": "/var/lib/docker/containers/bf76418f4ab69dff5892b1f53adcddbb5add2b4ed7b610359c1405a4dc7ab980/resolv.conf",
        "HostnamePath": "/var/lib/docker/containers/bf76418f4ab69dff5892b1f53adcddbb5add2b4ed7b610359c1405a4dc7ab980/hostname",
        "HostsPath": "/var/lib/docker/containers/bf76418f4ab69dff5892b1f53adcddbb5add2b4ed7b610359c1405a4dc7ab980/hosts",
        "LogPath": "/var/lib/docker/containers/bf76418f4ab69dff5892b1f53adcddbb5add2b4ed7b610359c1405a4dc7ab980/bf76418f4ab69dff5892b1f53adcddbb5add2b4ed7b610359c1405a4dc7ab980-json.log",
        "Name": "/docker_redis_1",
        "RestartCount": 0,
        "Driver": "overlay2",
        "Platform": "linux",
        "MountLabel": "",
        "ProcessLabel": "",
        "AppArmorProfile": "",
        "ExecIDs": null,
        "HostConfig": {
            "Binds": [
                "docker_redis_vol:/data:rw",
                "/root/docker/redis.conf:/etc/redis/redis.conf:rw"
            ],
            "ContainerIDFile": "",
            "LogConfig": {
                "Type": "json-file",
                "Config": {
                    "max-file": "10",
                    "max-size": "200k"
                }
            },
            "NetworkMode": "docker_redis_network",
            "PortBindings": {
                "6379/tcp": [
                    {
                        "HostIp": "",
                        "HostPort": "6379"
                    }
                ]
            },
            "RestartPolicy": {
                "Name": "always",
                "MaximumRetryCount": 0
            },
            "AutoRemove": false,
            "VolumeDriver": "",
            "VolumesFrom": [],
            "CapAdd": null,
            "CapDrop": null,
            "CgroupnsMode": "host",
            "Dns": [
                "8.8.8.8"
            ],
            "DnsOptions": null,
            "DnsSearch": [
                "example.com"
            ],
            "ExtraHosts": [
                "somehost:162.242.195.82",
                "otherhost:50.31.209.229"
            ],
            "GroupAdd": null,
            "IpcMode": "shareable",
            "Cgroup": "",
            "Links": null,
            "OomScoreAdj": 0,
            "PidMode": "host",
            "Privileged": false,
            "PublishAllPorts": false,
            "ReadonlyRootfs": false,
            "SecurityOpt": [
                "label:user:USER",
                "label:role:ROLE",
                "label=disable"
            ],
            "Tmpfs": {
                "/run": ""
            },
            "UTSMode": "",
            "UsernsMode": "host",
            "ShmSize": 67108864,
            "Sysctls": {
                "net.core.somaxconn": "1024",
                "net.ipv4.tcp_syncookies": "0"
            },
            "Runtime": "runc",
            "ConsoleSize": [
                0,
                0
            ],
            "Isolation": "default",
            "CpuShares": 0,
            "Memory": 0,
            "NanoCpus": 0,
            "CgroupParent": "",
            "BlkioWeight": 0,
            "BlkioWeightDevice": null,
            "BlkioDeviceReadBps": null,
            "BlkioDeviceWriteBps": null,
            "BlkioDeviceReadIOps": null,
            "BlkioDeviceWriteIOps": null,
            "CpuPeriod": 0,
            "CpuQuota": 0,
            "CpuRealtimePeriod": 0,
            "CpuRealtimeRuntime": 0,
            "CpusetCpus": "",
            "CpusetMems": "",
            "Devices": null,
            "DeviceCgroupRules": null,
            "DeviceRequests": null,
            "KernelMemory": 0,
            "KernelMemoryTCP": 0,
            "MemoryReservation": 0,
            "MemorySwap": 0,
            "MemorySwappiness": null,
            "OomKillDisable": false,
            "PidsLimit": null,
            "Ulimits": [
                {
                    "Name": "nproc",
                    "Hard": 65535,
                    "Soft": 65535
                },
                {
                    "Name": "nofile",
                    "Hard": 40000,
                    "Soft": 20000
                }
            ],
            "CpuCount": 0,
            "CpuPercent": 0,
            "IOMaximumIOps": 0,
            "IOMaximumBandwidth": 0,
            "MaskedPaths": [
                "/proc/asound",
                "/proc/acpi",
                "/proc/kcore",
                "/proc/keys",
                "/proc/latency_stats",
                "/proc/timer_list",
                "/proc/timer_stats",
                "/proc/sched_debug",
                "/proc/scsi",
                "/sys/firmware"
            ],
            "ReadonlyPaths": [
                "/proc/bus",
                "/proc/fs",
                "/proc/irq",
                "/proc/sys",
                "/proc/sysrq-trigger"
            ],
            "Init": true
        },
        "GraphDriver": {
            "Data": {
                "LowerDir": "/var/lib/docker/overlay2/fdd65a7b3dd4e2d3904fe5d38656a6ef209f838f7fb4eff82387cf58e63fd665-init/diff:/var/lib/docker/overlay2/f40df8bee5df02139b8842b49df50204a209f20ea55e90c5e679155d47f14052/diff:/var/lib/docker/overlay2/f262ebf707b84c4aaf15ad95fb5f3762a3de9f00e3fa80eb200e7d2974b47a71/diff:/var/lib/docker/overlay2/d7238b1c8820c4cc6345df77afe0f8a7d7074dee0d1483b78f794aca4730ab5c/diff:/var/lib/docker/overlay2/fea75636a73398782f4ce75ae4f2649857dcda914ac1a8978ede85dc612b7dd6/diff:/var/lib/docker/overlay2/03388075cf9f8ecaab7c1f0cd70bac5ca3cde5398b5b6910ff56400cac7d7c66/diff:/var/lib/docker/overlay2/04f6770d7d1240e23c1dff9a8302a998ecd99506d465de78ecc42463282538d3/diff",
                "MergedDir": "/var/lib/docker/overlay2/fdd65a7b3dd4e2d3904fe5d38656a6ef209f838f7fb4eff82387cf58e63fd665/merged",
                "UpperDir": "/var/lib/docker/overlay2/fdd65a7b3dd4e2d3904fe5d38656a6ef209f838f7fb4eff82387cf58e63fd665/diff",
                "WorkDir": "/var/lib/docker/overlay2/fdd65a7b3dd4e2d3904fe5d38656a6ef209f838f7fb4eff82387cf58e63fd665/work"
            },
            "Name": "overlay2"
        },
        "Mounts": [
            {
                "Type": "volume",
                "Name": "docker_redis_vol",
                "Source": "/var/lib/docker/volumes/docker_redis_vol/_data",
                "Destination": "/data",
                "Driver": "local",
                "Mode": "rw",
                "RW": true,
                "Propagation": ""
            },
            {
                "Type": "bind",
                "Source": "/root/docker/redis.conf",
                "Destination": "/etc/redis/redis.conf",
                "Mode": "rw",
                "RW": true,
                "Propagation": "rprivate"
            }
        ],
        "Config": {
            "Hostname": "bf76418f4ab6",
            "Domainname": "",
            "User": "",
            "AttachStdin": false,
            "AttachStdout": false,
            "AttachStderr": false,
            "ExposedPorts": {
                "6379/tcp": {}
            },
            "Tty": false,
            "OpenStdin": false,
            "StdinOnce": false,
            "Env": [
                "affinity:container==c3d082140a07e61738084405939a53abd90ad6d56450d70ca4347e3307db167c",
                "PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin",
                "GOSU_VERSION=1.12",
                "REDIS_VERSION=6.2.6",
                "REDIS_DOWNLOAD_URL=http://download.redis.io/releases/redis-6.2.6.tar.gz",
                "REDIS_DOWNLOAD_SHA=5b2b8b7a50111ef395bf1c1d5be11e6e167ac018125055daa8b5c2317ae131ab"
            ],
            "Cmd": [
                "redis-server",
                "/etc/redis/redis.conf"
            ],
            "Healthcheck": {
                "Test": [
                    "CMD",
                    "curl",
                    "-f",
                    "http://localhost"
                ],
                "Interval": 90000000000,
                "Timeout": 10000000000,
                "Retries": 3
            },
            "Image": "redis:latest",
            "Volumes": {
                "/data": {},
                "/etc/redis/redis.conf": {}
            },
            "WorkingDir": "/data",
            "Entrypoint": [
                "docker-entrypoint.sh"
            ],
            "OnBuild": null,
            "Labels": {
                "com.docker.compose.config-hash": "09aaa807a7358703e1a719294b4167daaf9bc7845d27af4dc753fa3407204e78",
                "com.docker.compose.container-number": "1",
                "com.docker.compose.oneoff": "False",
                "com.docker.compose.project": "docker",
                "com.docker.compose.project.config_files": "docker-compose.yml",
                "com.docker.compose.project.working_dir": "/root/docker",
                "com.docker.compose.service": "redis",
                "com.docker.compose.version": "1.26.0",
                "com.example.department": "Finance",
                "com.example.description": "Accounting webapp",
                "com.example.label-with-empty-value": ""
            },
            "StopSignal": "SIGUSR1",
            "StopTimeout": 90
        },
        "NetworkSettings": {
            "Bridge": "",
            "SandboxID": "275e877c39e11427ae85da409e87d6853571c86a215293f1367c7e8d9521b81a",
            "HairpinMode": false,
            "LinkLocalIPv6Address": "",
            "LinkLocalIPv6PrefixLen": 0,
            "Ports": {
                "6379/tcp": [
                    {
                        "HostIp": "0.0.0.0",
                        "HostPort": "6379"
                    },
                    {
                        "HostIp": "::",
                        "HostPort": "6379"
                    }
                ]
            },
            "SandboxKey": "/var/run/docker/netns/275e877c39e1",
            "SecondaryIPAddresses": null,
            "SecondaryIPv6Addresses": null,
            "EndpointID": "",
            "Gateway": "",
            "GlobalIPv6Address": "",
            "GlobalIPv6PrefixLen": 0,
            "IPAddress": "",
            "IPPrefixLen": 0,
            "IPv6Gateway": "",
            "MacAddress": "",
            "Networks": {
                "docker_redis_network": {
                    "IPAMConfig": null,
                    "Links": [
                        "redis_1:redis_1"
                    ],
                    "Aliases": [
                        "bf76418f4ab6",
                        "redis",
                        "alias3",
                        "alias1"
                    ],
                    "NetworkID": "74f09926f4d034f2ae63ff1a46590d883562e711814a0dcce7e683284e407c31",
                    "EndpointID": "caf62eb67f9f47fe3de0cb65900cfcead21e3c6d935778e22874953a1c9be9f3",
                    "Gateway": "172.21.0.1",
                    "IPAddress": "172.21.0.2",
                    "IPPrefixLen": 16,
                    "IPv6Gateway": "",
                    "GlobalIPv6Address": "",
                    "GlobalIPv6PrefixLen": 0,
                    "MacAddress": "02:42:ac:15:00:02",
                    "DriverOpts": null
                }
            }
        }
    }
]

1.build

在创建服务时使用

services:
  webapp:
    build: ./dir
1)context

指定包含Dockerfile的目录路径或git仓库url。该目录是发送给Docker守护进程(Daemon)的构建上下文(context)。当配置的值是相对路径时,它将被解释为相对于Compose配置文件的路径。

services:
  webapp:
    build:
      context: ./dir
2)dockerfile

指定Dockerfile文件。Compose会使用指定的Dockerfile文件构建镜像,但必须要指定构建上下文路径。

services:
  webapp:
    build:
      context: ./dir
      dockerfile: Dockerfile-alternate
3)args

添加构建参数,这些只能在构建过程中访问的环境变量。

services:
  webapp:
    build:
      context: ./dir
      dockerfile: Dockerfile-alternate
      args:
        - buildno=1
        - gitcommithash=cdc3b19
4)cache_from

指定缓存解析镜像列表

services:
  webapp:
    build:
      context: ./dir
      cache_from:
        - alpine:latest
        - corp/web_app:3.14
5)labels

将元数据以标签的形式添加到生成的镜像中。可以使用数组或字典两种格式。推荐使用反向DNS写法以避免和其他应用的标签冲突。

services:
  webapp:
    build:
      context: ./dir
      labels:
        com.example.description: "Accounting webapp"
        com.example.department: "Finance"
        com.example.label-with-empty-value: ""
6)network

设置容器网络连接以获取构建过程中的RUN指令。

services:
  webapp:
    build:
      context: ./dir
      network: custom_network_1
7)shm_size(shared memory size)

指定容器的/dev/shm分区大小。指定的值为表示字节数的整数值或表示字节值的字符串。

services:
  webapp:
    build:
      context: ./dir
      shm_size: 10000000
8)target

指定在Dockerfile中定义的构建阶段,即镜像只构建到指定阶段(dev、test、prod等)就停止构建。

services:
  webapp:
    build:
      context: ./dir
      target: prod

2.cap_add、cap_drop

添加或删除容器内核能力(capability)

容器拥有所有内核能力
services:
  webapp:
    build:
      cap_add:
        - ALL
容器拥有删除NET_ADMIN和SYS_ADMIN能力
services:
  webapp:
    cap_drop:
      - NET_ADMIN
      - SYS_ADMIN
# docker inspect --format='{{.Name}}|''{{.HostConfig.CapAdd}}|''{{ .HostConfig.CapDrop}}' 91abfc78b2fe
/docker_redis_1|[]|[]

3.cgroup_parent

为容器指定一个可选的父控制组。

services:
  webapp:
    cgroup_parent: m-executor-abcd
# docker inspect --format='{{.Name}}|''{{.HostConfig.CgroupParent}}' 91abfc78b2fe
/docker_redis_1|

4.command

覆盖容器启动后默认执行的命令。可以写成字符串形式。

services:
  webapp:
    command: bundle exec thin -p 3000

# docker inspect --format='{{.Name}}|''{{.Config.Cmd}}' 91abfc78b2fe
/docker_redis_1|[redis-server /etc/redis/redis.conf]

5.config

为每个服务授予对配置(configs)的访问权限。支持short和long两种格式的语法。
注意:该配置(config)必须已存在或者在堆栈文件顶层configs配置项中定义,否则堆栈部署将失败。

1)Short syntax

Short syntax仅指定config名称来授予容器访问config的权限并将其挂载到容器的/<config_name>上。source名称和目标挂载点都设置为config名称。

services:
  redis:
    image: redis:latest
    deploy:
      replicas: 1
    configs:
      - my_config
      - my_other_config
configs:
  my_config:
    file: ./my_config.txt
  my_other_config:
    external: true
2)Long syntax

Long syntax提供了在服务的任务容器内如何创建config的更多粒度:
source:Docker中存在的config名称。
target:指定要挂载到服务的任务容器的文件的路径加名称。如果未指定,默认为/。
uid和gid:指定服务的任务容器所拥有的该文件的UID或GID。如果在LInux中未指定,两者都默认为0。不支持Windows。
mode:以八进制表示法指定要挂载到服务的任务容器的文件权限。例如,0444代表可读。默认值就为0444。config内容已挂载到临时文件系统中,所以不可写,如果设置了可写位将被忽略。可以设置可执行位。如果不熟悉UNIX文件权限模式,可以使用权限计算器 。

services:
  redis:
    image: redis:latest
    deploy:
      replicas: 1
    configs:
      - source: my_config
        target: /redis_config
        uid: '103'
        gid: '103'
        mode: 0440
configs:
  my_config:
    file: ./my_config.txt
  my_other_config:
    external: true

6.container_name

指定自定义容器的名称,而不是使用默认名称。因为Docker容器的名称必须唯一,所以为一个服务指定了自定义容器名称后,该服务不能进行扩展。如果尝试为该服务扩容将会导致错误。

services:
  webapp:
    container_name: my-web-container

# docker inspect --format='{{.Name}}' 91abfc78b2fe
/docker_redis_1

7.credential_spec

配置托管服务帐户的凭据规格(credential spec)。此选项仅用于使用Windows容器的服务。credential_spec配置必须采用file://或registry://格式。使用file:时,引用的文件必须存在于Docker数据目录的CredentialSpecs子目录中,在Windows上,Docker数据目录默认为C:\ProgramData\Docker\。以下示例从名为C:\ProgramData\Docker\CredentialSpecs\my-credential-spec.json的文件加载凭证规格:

services:
  myservice:
    image: myimage:latest
    credential_spec:
      file: my-credential-spec.json
services:
  myservice:
    image: myimage:latest
    credential_spec:
      config: my_credential_spec
 
configs:
  my_credentials_spec:
    file: ./my-credential-spec.json|

8.depends_on

指定服务之间的依赖关系,解决服务启动先后顺序问题。指定服务之间的依赖关系,将会导致以下行为:
docker-compose up以依赖顺序启动服务。
docker-compose up SERVICE会自动包含SERVICE的依赖项。
docker-compose stop以依赖顺序停止服务。
但是服务不会等待该服务所依赖的服务完全启动或停止之后才启动或停止。

services:
  web:
    build: .
    depends_on:
      - db
      - redis
  redis:
    image: redis
  db:
    image: postgres
使用docker-compose up启动时会先启动db和redis,最后才启动web。
使用docker-compose up web启动web时,也会启动db和redis,因为在web服务中指定了依赖关系。
使用docker-compose stop在停止时也在web之前先停止db和redis。

9.deploy

指定部署和运行服务的相关配置。该配置仅在swarm mode下生效,并只能通过docker stack deploy命令部署,docker-compose up和docker-compose run命令将被忽略。

services:
  redis:
    image: redis:alpine
    deploy:
      replicas: 6
      placement:
        max_replicas_per_node: 1
      update_config:
        parallelism: 2
        delay: 10s
      restart_policy:
        condition: on-failure

deploy配置项中包含endpoint_mode、labels、mode、placement、max_replicas_per_node、replicas、resources、restart_policy、rollback_config、update_config等子配置项。

# docker service inspect 3x9ypsh2sx5a
[
    {
        "ID": "3x9ypsh2sx5amr4wrs1or2zt8",
        "Version": {
            "Index": 40
        },
        "CreatedAt": "2023-03-16T07:34:04.154820913Z",
        "UpdatedAt": "2023-03-16T07:34:04.154820913Z",
        "Spec": {
            "Name": "sharp_mendeleev",
            "Labels": {},
            "TaskTemplate": {
                "ContainerSpec": {
                    "Image": "redis:latest@sha256:db485f2e245b5b3329fdc7eff4eb00f913e09d8feb9ca720788059fdc2ed8339",
                    "Init": false,
                    "StopGracePeriod": 10000000000,
                    "DNSConfig": {},
                    "Isolation": "default"
                },
                "Resources": {
                    "Limits": {},
                    "Reservations": {}
                },
                "RestartPolicy": {
                    "Condition": "any",
                    "Delay": 5000000000,
                    "MaxAttempts": 0
                },
                "Placement": {
                    "Platforms": [
                        {
                            "Architecture": "amd64",
                            "OS": "linux"
                        },
                        {
                            "OS": "linux"
                        },
                        {
                            "OS": "linux"
                        },
                        {
                            "Architecture": "arm64",
                            "OS": "linux"
                        },
                        {
                            "Architecture": "386",
                            "OS": "linux"
                        },
                        {
                            "Architecture": "mips64le",
                            "OS": "linux"
                        },
                        {
                            "Architecture": "ppc64le",
                            "OS": "linux"
                        },
                        {
                            "Architecture": "s390x",
                            "OS": "linux"
                        }
                    ]
                },
                "ForceUpdate": 0,
                "Runtime": "container"
            },
            "Mode": {
                "Replicated": {
                    "Replicas": 1
                }
            },
            "UpdateConfig": {
                "Parallelism": 1,
                "FailureAction": "pause",
                "Monitor": 5000000000,
                "MaxFailureRatio": 0,
                "Order": "stop-first"
            },
            "RollbackConfig": {
                "Parallelism": 1,
                "FailureAction": "pause",
                "Monitor": 5000000000,
                "MaxFailureRatio": 0,
                "Order": "stop-first"
            },
            "EndpointSpec": {
                "Mode": "vip"
            }
        },
        "Endpoint": {
            "Spec": {}
        }
    }
]
1)endpoint_mode

为外部客户端连接到swarm指定服务发现方式:
endpoint_mode: vip:Docker为服务分配了一个前端的虚拟IP,客户端通过该虚拟IP访问网络上的服务。Docker在客户端和服务的可用工作节点之间进行路由请求,而无须关系有多少节点正在参与该服务或这些节点的IP地址或者端口。这是默认设置。
endpoint_mode: dnsrr:DNS轮询(DNSRR),Docker设置服务的DNS条目,以便对服务名称的DNS查询返回IP地址列表,并且客户端通过轮询的方式直接连接到其中之一。

version: "3.2"
services:
  wordpress:
    ...
    deploy:
      mode: replicated
      replicas: 2
      endpoint_mode: vip
默认为endpoint_mode: vip
# docker service inspect --format='{{.Spec.TaskTemplate.ContainerSpec.Image}}----''{{.Spec.EndpointSpec.Mode}}' 3x9ypsh2sx5a
redis:latest@sha256:db485f2e245b5b3329fdc7eff4eb00f913e09d8feb9ca720788059fdc2ed8339----vip
2)labels

指定服务的标签。这些标签仅在服务上设置,而不在服务的任何容器上设置。

version: "3.8"
services:
  web:
    image: web
    deploy:
      labels:
        com.example.description: "This label will appear on the web service"
默认Lables为空
# docker service inspect --format='{{.Spec.TaskTemplate.ContainerSpec.Image}}----''{{.Spec.Labels}}' 3x9ypsh2sx5a
redis:latest@sha256:db485f2e245b5b3329fdc7eff4eb00f913e09d8feb9ca720788059fdc2ed8339----map[]
3)mode

指定服务的容器副本模式。可以为:
global:每个swarm节点只有一个该服务容器。
replicated:整个集群中存在指定份数的服务容器副本,为默认值。

services:
  worker:
    image: dockersamples/examplevotingapp_worker
    deploy:
      mode: global
# docker service inspect --format '{{.Spec.Mode.Replicated.Replicas}}' 3x9ypsh2sx5a
1
4)placement

指定constraints和preferences。constraints可以指定只有符合要求的节点上才能运行该服务容器,preferences可以指定容器分配策略。例如,指定集群中只有满足node.rolemanager和engine.labels.operatingsystemubuntu 18.04条件的节点上能运行db服务容器,并且在满足node.labels.zone的节点上均匀分配:

services:
  db:
    image: postgres
    deploy:
      placement:
        constraints:
          - "node.role==manager"
          - "engine.labels.operatingsystem==ubuntu 18.04"
        preferences:
          - spread: node.labels.zone
# docker service inspect --format '{{.Spec.TaskTemplate.Placement.Platforms}}' 3x9ypsh2sx5a
[{amd64 linux} { linux} { linux} {arm64 linux} {386 linux} {mips64le linux} {ppc64le linux} {s390x linux}]
5)max_replicas_per_node

如果服务的容器副本模式为replicated(默认),可以指定每个节点上运行的最大容器副本数量。当指定的容器副本数量大于最大容器副本数量时,将引发no suitable node (max replicas per node limit exceed)错误。

version: "3.8"
services:
  worker:
    ...
    deploy:
      mode: replicated
      replicas: 6
      placement:
        max_replicas_per_node: 1
6)replicas

如果服务的容器副本模式为replicated(默认),指定运行的容器副本数量。

services:
  worker:
    ...
    deploy:
      mode: replicated
      replicas: 6
# docker service inspect --format '{{.Spec.Mode.Replicated.Replicas}}' 3x9ypsh2sx5a
7)resources

配置资源限制。例如,指定redis服务使用的cpu份额为25%到50%,内存为20M到50M:
在V3版Compose配置文件中的改变:resources取代了V3版之前的Compose配置文件中旧的资源限制的配置项,包括cpu_shares、cpu_quota、cpuset、mem_limit、memswap_limit、mem_swappiness。
在非swarm mode容器上设置资源限制:此处的resources配置项只有用于deploy配置项之下和swarm mode。如果要在非swarm mode部署中设置资源限制,需使用V2版Compose配置文件中CPU、memory和其他资源的配置项。

services:
  redis:
    ...
    deploy:
      resources:
        limits:
          cpus: '0.50'
          memory: 50M
        reservations:
          cpus: '0.25'
          memory: 20M
# docker service inspect --format '{{.Spec.TaskTemplate.Resources.Limits}}---{{.Spec.TaskTemplate.Resources.Reservations}}' 3x9ypsh2sx5a
{0 0 0}---{0 0 []}
8)restart_policy

指定容器的重启策略。代替restart。有以下配置选项:
condition:重启策略。值可以为none、on-failure或any,默认为any。
delay:尝试重启的等待时间。指定为持续时间(durations)。默认值为0。
max_attempts:重启最多尝试的次数,超过该次数将放弃。默认为永不放弃。如果在window配置的时间之内未成功重启,则此次尝试不计入max_attempts的值。
window:在决定重启是否成功之前的等待时间。指定为持续时间(durations)。默认值为立即决定。
例如,指定重启策略为失败时重启,等待5s,重启最多尝试3次,决定重启是否成功前的等待时间为120s:

services:
  redis:
    ...
    deploy:
      restart_policy:
        condition: on-failure
        delay: 5s
        max_attempts: 3
        window: 120s
# docker service inspect --format '{{.Spec.TaskTemplate.RestartPolicy.Condition}},''{{.Spec.TaskTemplate.RestartPolicy.Delay}},'{{.Spec.TaskTemplate.RestartPolicy.MaxAttempts}}'' 3x9ypsh2sx5a
any,5s,0
9)rollback_config

配置在更新失败的情况下如何回滚服务。有以下配置选项:
parallelism:一次回滚的容器数量。如果设置为0,则所有容器同时回滚。
delay:每个容器组之间的回滚所等待的时间。默认值为0s。
failure_action:回滚失败后的行为。有continue和pause两种,默认值为pause。
monitor:每次任务更新后监视失败的时间(ns|us|ms|s|m|h)。默认值为0s。
max_failure_ratio:在回滚期间能够容忍的最大失败率。默认值为0。
order:设置回滚顺序。stop-first为在开启新任务之前停止旧任务,start-first为首先启动新任务,和正在运行任务短暂重叠,默认值为stop-first。

            "RollbackConfig": {
                "Parallelism": 1,
                "FailureAction": "pause",
                "Monitor": 5000000000,
                "MaxFailureRatio": 0,
                "Order": "stop-first"
            },
# docker service inspect --format '{{index .Spec.RollbackConfig}}' 3x9ypsh2sx5a
{1 0s pause 5s 0 stop-first}
10)update_config

配置如何更新服务。该配置对滚动更新很有用。有以下配置选项:
parallelism:一次更新的容器数量。
delay:更新一组容器之间的等待时间。
failure_action:更新失败后的行为。有continue、rollback和pause三种,默认值为pause。
monitor:每次任务更新后监视失败的时间(ns|us|ms|s|m|h)。默认值为0s。
max_failure_ratio:在更新期间能够容忍的最大失败率。
order:设置更新顺序。stop-first为在开启新任务之前停止旧任务,start-first为首先启动新任务,和正在运行任务短暂重叠,默认值为stop-first。注意该配置项在3.4版的配置文件格式中加入,仅支持3.4或更高版本。
例如,指定每次更新2个容器,更新等待时间10s,更新顺序为先停止旧任务再开启新任务:

services:
  vote:
    ...
    deploy:
      replicas: 2
      update_config:
        parallelism: 2
        delay: 10s
        order: stop-first
            "UpdateConfig": {
                "Parallelism": 1,
                "FailureAction": "pause",
                "Monitor": 5000000000,
                "MaxFailureRatio": 0,
                "Order": "stop-first"
            },
# docker service inspect --format '{{index .Spec.UpdateConfig}}' 3x9ypsh2sx5a
{1 0s pause 5s 0 stop-first}
11)Not supported for docker stack deploy

以下为支持docker-compose up和docker-compose run,不支持docker stack deploy或deploy配置项的配置项:

build
cgroup_parent
container_name
devices
tmpfs
external_links
links
network_mode
restart
security_opt
userns_mode

10.devices

指定设备映射列表。与Docker客户端create的--device选项类似。

  devices:
    - "/dev/ttyUSB0:/dev/ttyUSB0"
# docker inspect --format '{{.HostConfig.Devices}}' 241f80a43637
[]

11.dns

自定义DNS服务器。可以是一个值或一个列表。例如:

services:
  redis:
    ...
    dns: 8.8.8.8
    
    dns:
      - 8.8.8.8
      - 9.9.9.9
# docker inspect --format '{{.HostConfig.Dns}}' b03c7080b0b6
[8.8.8.8]

12.dns_search

自定义DNS搜索域。可以是一个值或一个列表。例如:
services:
redis:
...
dns_search: example.com

dns_search:
  - dc1.example.com
  - dc2.example.com
# docker inspect --format '{{.HostConfig.DnsSearch}}' 1c705ea79a52
[example.com]

13.entrypoint

覆盖默认的入口命令。注意设置entrypoint会覆盖所有在服务镜像上使用Dockerfile的ENTRYPOINT指令设置的默认入口命令,并清除掉服务镜像上任何使用Dockerfile的CMD指令设置的启动容器时默认执行的命令。可以写成字符串形式,例如:

services:
  redis:
    ...
    entrypoint: /code/entrypoint.sh
也可以写成JSON数组形式,例如:
    entrypoint: ["php", "-d", "memory_limit=-1", "vendor/bin/phpunit"]
# docker inspect --format '{{.Config.Entrypoint}}' 1c705ea79a52
[docker-entrypoint.sh]

14.env_file

从文件中获取环境变量。可以是一个值或一个列表。例如:

services:
  redis:
    ...
    env_file: .env

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

如果指定了Compose配置文件,env_file路径为相对于该文件所在目录的路径。如果环境文件中设置有与environment选项同名的变量,将以后者为准,无论这些变量的值是空还是未定义。其中环境文件每行都以VAR=VAL格式声明环境变量,以#开头的行被解析为注释,和空行一样将被忽略。环境文件示例如下:

# Set Rails/Rack environment
RACK_ENV=development

如果变量的值被引号引起来(通常是shell变量),则引号也包含在传递给Compose的值中。如果以列表的形式同时指定了多个环境文件,列表中文件的顺序对于给多次出现的环境变量确定值十分重要,且列表中的文件是从上到下处理的。如果指定了多个环境文件且有至少两个文件声明了相同名称但不同值的环境变量,那么指定列表中顺序靠下的文件将覆盖顺序靠上的文件中的相同名称的环境变量的值。例如:

services:
  some-service:
    env_file:
      - a.env
      - b.env

如果a.env中有VAR=1,b.env中有VAR=2,则最终$VAR=2。
注意:这里所说的环境变量是针对宿主机的Compose而言的,如果在服务中指定了build配置项,那么这些变量并不会进入构建过程中,如果要定义构建时用的环境变量首选build的arg子选项。

15.environment

设置环境变量。可以使用数组或字典两种格式。任何布尔类型的值都必须用引号引起来,以便解析器将它们解释为字符串。值设置了键没设置值的环境变量可以在运行Compose的主机环境中解析它们的值,这对于使用密钥和特定于主机的值用处很大。例如:

services:
  some-service:
    environment:
      RACK_ENV: development
      SHOW: 'true'
      SESSION_SECRET:
  
    environment:
      - RACK_ENV=development
      - SHOW=true
      - SESSION_SECRET

注意:这里所说的环境变量是针对宿主机的Compose而言的,如果在服务中指定了build配置项,那么这些变量并不会进入构建过程中,如果要定义构建时用的环境变量首选build的arg子选项。

# docker inspect --format '{{.Config.Env}}' 1c705ea79a52
[affinity:container==b03c7080b0b697c58833d7ee59a74301dd76e46655c994befc1eca99ef760e03 PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin GOSU_VERSION=1.12 REDIS_VERSION=6.2.6 REDIS_DOWNLOAD_URL=http://download.redis.io/releases/redis-6.2.6.tar.gz REDIS_DOWNLOAD_SHA=5b2b8b7a50111ef395bf1c1d5be11e6e167ac018125055daa8b5c2317ae131ab]

16.expose

暴露指定端口,但不映射到宿主机,只被连接的服务访问。只能指定内部端口。例如:

services:
  some-service:
    expose:
      - "3000"
      - "8000"
# docker inspect --format '{{.Config.ExposedPorts}}' 1c705ea79a52
map[6379/tcp:{}]

17.external_links

链接到docker-compose.yml外部的容器,甚至并非Compose管理的外部容器,特别是对于提供共享或公共服务的容器。在同时指定容器名称和链接别名(CONTAINER:ALIAS)时,external_links与旧版本中的配置项links有类似的语义。例如:

services:
  some-service:
    external_links:
      - redis_1
      - project_db_1:mysql
      - project_db_1:postgresql

注意:Compose项目里面的容器连接到外部容器的前提条件是外部容器中必须至少有一个容器连接到与项目内的服务的同一个网络里面。建议使用networks代替旧版本中的配置项Links。
使用docker stack deploy时的注意事项:在swarm mode下部署堆栈时,external_links配置项将被忽略。

# docker inspect --format '{{.NetworkSettings.Networks.docker_redis_network.Links}}'  f43a1da40a04
[redis_1:redis_1]

18.extra_hosts

添加主机名到IP的映射。使用和Docker客户端中的--add-host的参数一样的值。例如:

services:
  some-service:
    extra_hosts:
      - "somehost:162.242.195.82"
      - "otherhost:50.31.209.229"

会在启动后的服务容器中的/etc/hosts文件中添加如下两条具有主机名和IP地址的条目:

162.242.195.82  somehost
50.31.209.229   otherhost
# docker inspect --format '{{.HostConfig.ExtraHosts}}' 5ed09a98c65d
[somehost:162.242.195.82 otherhost:50.31.209.229]

19.healthcheck

配置运行检查以确定服务容器是否健康。支持以下配置选项:
test:指定健康检测的方法。
interval:启动容器到进行健康检查的间隔时间以及两次健康检查的间隔时间。
timeout:单次健康检查的超时时间,超过该时间该次健康检查失败。
retries:健康检查失败后的最大重试次数,重试了最大次数依然失败,容器将被视为unhealthy。
start_period:为需要时间引导的容器提供的初始化时间,在此期间检查失败将不计入最大重试次数,但是如果在启动期间健康检查成功,则会将容器视为已启动,并且所有连续失败将计入最大重试次数。
其中interval、timeout和start_period都被指定为持续时间(durations)。start_period是在3.4版的配置文件格式中加入。test必须是字符串或JSON数组格式。如果是JSON数组格式,第一项必须是NONE、CMD或CMD-SHELL其中之一。如果是字符串格式,则等效于指定CMD-SHELL后跟该字符串的JSON数组格式。

例如以下示例,指定检测方法为访问http://localhost,健康检查间隔时间为1m30s,健康检查超时时间为10s,重试次数为3,启动容器后等待健康检查的初始化时间为40s:

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

例如以下示例,两种形式等效:

test: ["CMD-SHELL", "curl -f http://localhost || exit 1"]
test: curl -f https://localhost || exit 1

使用disable: true可以设置镜像禁用所有健康检查,相对于test: ["NONE"]。例如:

services:
  some-service:
    healthcheck:
      disable: true
# docker inspect --format '{{.Config.Healthcheck}}' f1b65c983797
{[CMD curl -f http://localhost] 1m30s 10s 0s 3}

            "Healthcheck": {
                "Test": [
                    "CMD",
                    "curl",
                    "-f",
                    "http://localhost"
                ],
                "Interval": 90000000000,
                "Timeout": 10000000000,
                "Retries": 3
            },

20.image

指定要从中启动容器的镜像。可以写仓库/标签(repository/tag)或镜像ID。示例如下:

services:
  redis:
    image: redis:latest
    
    image: redis
    image: ubuntu:18.04
    image: tutum/influxdb
    image: example-registry.com:4000/postgresql
    image: a4bc65fd

如果镜像不存在,Compose会自动拉取镜像,除非指定了build,这种情况下会使用指定选项构建镜像并给镜像打上指定标签。

# docker inspect --format '{{.Config.Image}}' f1b65c983797
redis:latest

21.init

在容器内运行一个初始化程序以转发信号并获取进程。设置为true即可为服务启动此功能。例如:

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

注意:默认使用的初始化二进制文件是Tini,并安装在主机守护进程的/usr/libexec/docker-init。可以通过Daemon configuration file中的init-path将守护进程配置为使用自定义的初始化二进制文件 。

# docker inspect --format '{{.HostConfig.Init}}' 77a502571344
true

22.isolation

指定容器的隔离技术。Linux上只支持default值。Windows上支持default、process和hyperv这三个值。

services:
  web:
    isolation: default
# docker inspect --format '{{.HostConfig.Isolation}}'  6d497ef22a13
default

23.labels

将元数据以标签的形式添加到容器中。可以使用数组或字典两种格式。例如:

services:
  web:
    labels:
      com.example.description: "Accounting webapp"
      com.example.department: "Finance"
      com.example.label-with-empty-value: ""
# docker inspect --format '{{.Config.Labels}}' 6d497ef22a13
map[com.docker.compose.config-hash:cfba4c9fafbd05de296e709055a74dfd9391f7de20e9c3f25cdc49801db6393b com.docker.compose.container-number:1 com.docker.compose.oneoff:False com.docker.compose.project:docker com.docker.compose.project.config_files:docker-compose.yml com.docker.compose.project.working_dir:/root/docker com.docker.compose.service:redis com.docker.compose.version:1.26.0 com.example.department:Finance com.example.description:Accounting webapp com.example.label-with-empty-value:]

24.links

警告:--link是Docker的遗留功能。它最终可能会被删除。建议您使用用户自定义网络代替--link来进行两个容器间的通信。用户自定义的网络不支持--link在容器之间共享的环境变量的功能。但是可以使用例如数据卷之类的其他机制以更可控的方式在容器之间共享环境变量。
链接到其他服务中的容器。可以使用"SERVICE:ALIAS"或"SERVICE"的格式,其中SERVICE为服务名称,ALIAS为链接别名。

services:
  web:
    links:
      - "db"
      - "db:database"
      - "redis"

链接服务的容器可以通过与别名相同的主机名访问,如果未指定别名,则可以使用服务名。默认情况下,不需要链接即可使服务进行通信,任何服务都可以使用该服务的名称访问任何其他服务。链接也可以和depends_on一样表示服务之间的依赖关系 ,因此可以确定服务启动的顺序。
注意:如果同时定义链接和网络,则它们之间具有链接的服务必须共享至少一个公共网络才能进行通信。
使用docker stack deploy时的注意事项:在swarm mode下部署堆栈时,links配置项将被忽略。

# docker inspect --format '{{.NetworkSettings.Networks.docker_redis_network.Links}}'  f43a1da40a04

25.logging

服务的日志配置。例如:

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

driver配置项指定服务容器的日志驱动,与docker run中的--log-driver选项一样。默认值为json-file,这里列举三种日志驱动类型:

driver: "json-file"
driver: "syslog"
driver: "none"

使用options配置项为日志驱动指定日志记录选项,与docker run中的--log-opt选项一样。例如:
默认日志驱动json-file具有限制日志存储量的选项。例如以下示例,max-size设置最大存储大小为200k,max-file设置存储的最大文件数为10,随着日志超过最大限制,将删除较旧的日志文件以允许存储新日志:

services:
  web:
    logging:
      options:
        max-size: "200k"
        max-file: "10"
            "LogConfig": {
                "Type": "json-file",
                "Config": {
                    "max-file": "10",
                    "max-size": "200k"
                }
            },
# docker inspect --format '{{.HostConfig.LogConfig}}' 38067601e2e3
{json-file map[max-file:10 max-size:200k]}

26.network_mode

设置网络模式。使用和Docker客户端中的--network的参数一样的值,格式为service:[service name]。可以指定使用服务或者容器的网络。示例如下:

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

注意事项:
在swarm mode下部署堆栈时,该选项将被忽略。
network_mode: "host"不能与links配置项混用。
network_mode不能与networks配置项混用。

当用netorks配置项时
# docker inspect --format '{{.HostConfig.NetworkMode}}' 38067601e2e3
docker_redis_network
当设置network_mode: "bridge"
# docker inspect --format '{{.HostConfig.NetworkMode}}' d137058708eb
bridge

27.networks

指定所加入的网络。需要在顶层networks配置项中引入具体的网络信息。

services:
  redis:
    ...
    networks:
      - redis_network
      - other-network
# docker inspect --format '{{.HostConfig.NetworkMode}}' 38067601e2e3
docker_redis_network
1)aliases

指定服务在此网络上的别名(备用主机名)。同一网络上的其他容器可以使用服务名称或此别名来连接到服务的任何一个容器。由于aliases属于网络范围,因此同一服务在不同的网络上可以具有不同的别名。例如:

services:
  redis:
    ...
    networks:
      redis_network:
        aliases:
          - alias1
          - alias3
                    "Aliases": [
                        "redis",
                        "alias1",
                        "2c1fc62e6cb1",
                        "alias3"
                    ],

# docker inspect --format '{{.NetworkSettings.Networks.docker_redis_network}}' 2c1fc62e6cb1
{<nil> [redis_1:redis_1] [redis alias1 2c1fc62e6cb1 alias3] 74f09926f4d034f2ae63ff1a46590d883562e711814a0dcce7e683284e407c31 a8cca1aecb9a3283a1b49fee318acd956a33358837690632c12209dc21b33894 172.21.0.1 172.21.0.2 16   0 02:42:ac:15:00:02 map[]}
# docker inspect --format '{{.NetworkSettings.Networks.docker_redis_network.Aliases}}' 2c1fc62e6cb1
[redis alias1 2c1fc62e6cb1 alias3]

在以下示例中,提供了web、worker和db三个服务,以及new和legacy两个网络:

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:

在该例中,可以通过主机名db或database在new网络上访问db服务,通过db或mysql在legacy网络上访问db服务。
注意:网络范围内的别名可以被多个容器甚至多个服务共享。如果是这样,则不能保证名称恰好解析到哪一个容器。

2)ipv4_address、ipv6_address

加入网络后,为此服务的容器指定一个静态IP地址。在顶层networks配置项中的相应网络配置必须有子网配置覆盖每个静态地址的ipam配置。例如:

version: "3.8"
services:
  app:
    image: nginx:alpine
    networks:
      app_net:
        ipv4_address: 172.16.238.10
        ipv6_address: 2001:3984:3989::10
 
 
networks:
  app_net:
    ipam:
      driver: default
      config:
        - subnet: "172.16.238.0/24"
        - subnet: "2001:3984:3989::/64"

注意:如果需要IPv6寻址,则必须使用V2.x版本的Compose配置文件并设置顶层networks配置项下的enable_ipv6选项。在当前swarm mode下IPv6选项不会起作用。

28.pid

跟主机系统共享进程命名空间。

services:
  redis:
    pid: "host"

将PID模式设置为主机PID模式,打开该选项的容器之间,以及容器和宿主机操作系统之间可以通过进程ID来相互访问和操作

# docker inspect --format '{{.State.Pid}}' 2c1fc62e6cb1
1837303
# ps -ef|grep 1837303
root     1837303 1837284  0 05:58 ?        00:00:00 /sbin/docker-init -- docker-entrypoint.sh redis-server /etc/redis/redis.conf
systemd+ 1837351 1837303  0 05:58 ?        00:00:00 redis-server *:6379

29.posts

暴露端口。

1)Long syntax

注意端口映射与network_mode: host不兼容。支持short和long两种格式的语法。short语法可以使用HOST:CONTAINER的格式指定端口映射,也可以指定容器端口,宿主机会随机选择临时端口进行映射。例如:

services:
  redis:
    ports:
      - "6379:6379"

      - "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:CONTAINE格式来映射端口时,如果使用的容器端口小于60可能会得到错误得结果,因为YAML将会解析xx:yy这种数字格式为60进制,因此建议始终采用字符串格式来指定端口映射。

# docker inspect --format '{{.NetworkSettings.Ports}}' 2c1fc62e6cb1
map[6379/tcp:[{0.0.0.0 6379} {:: 6379}]]
2)Short syntax

long语法支持配置short语法中不支持的附加字段。这些附加字段如下:
target:指定容器内的端口。
published:指定公开的端口。
protocol:指定端口协议(tcp或udp)。
mode:使用host在每个节点公开一个主机端口,或使用ingress对swarm mode端口进行负载均衡。

services:
  redis:
    ports:
      - target: 80
        published: 8080
        protocol: tcp
        mode: host

30.restart

指定重启策略。例如想要在容器退出时总是会重启容器,指定以下重启策略:
一共支持以下重启策略:
no:在任何情况下都不会重启容器。默认的重启策略。
always:在容器退出时总是重启容器。
on-failure:在容器以非0状态码退出时才会重启。
unless-stopped:在容器退出时总是重启容器,但是不考虑在Docker守护进程启动时就已经停止了的容器。

services:
  redis:
    restart: "no"
    restart: always
    restart: on-failure
    restart: unless-stopped

使用docker stack deploy时的注意事项:在swarm mode下部署堆栈时,restart配置项将被忽略。

# docker inspect --format '{{.HostConfig.RestartPolicy}}' 2c1fc62e6cb1
{always 0}
            "RestartPolicy": {
                "Name": "always",
                "MaximumRetryCount": 0
            },

31.secrets

为每个服务授予对保密数据(secrets)的访问权限。支持short和long两种格式的语法。
使用docker stack deploy时的注意事项:该保密数据(secret)必须已存在或者在Compose配置文件顶层secrets配置项中定义,否则堆栈部署将失败。

1)Short syntax

short语法仅指定secret名称来授予容器访问secret数据的权限并将其挂载到容器的/run/secrets/<secret_name>上。source名称和目标挂载点都设置为secret名称。例如以下示例,授予了redis服务对secrets的my_secret和my_other_secret的访问权限,其中my_secret的值设置到文件./my_secret.txt的内容中,my_other_secret定义为外部资源,这意味着它已经在Docker中通过运行docker secret create命令或其他堆栈部署进行定义,如果外部secret不存在,堆栈部署将会失败并显示secret not found错误:

version: "3.9"
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
2)Long syntax

long语法提供了在服务的任务容器内如何创建secret的更多粒度:
source:Docker中存在的secret名称。
target:指定要挂载到服务的任务容器的/run/secrets/中的文件名称。如果未指定,默认为source的值。
uid和gid:指定服务的任务容器的/run/secrets/中所拥有的该文件的UID或GID。如果未指定,两者都默认为0。
mode:以八进制表示法指定要挂载到服务的任务容器的/run/secrets/中的文件权限。例如,0444代表可读。默认值在Docker 1.13.1为0000,在较新版本为0444。secret内容已挂载到临时文件系统中,所以不可写,如果设置了可写位将被忽略。可以设置可执行位。如果不熟悉UNIX文件权限模式,可以使用权限计算器 。
例如以下示例,指定secret名称为my_secret,授予redis服务对my_secret的访问权限,指定要挂载到redis服务的任务容器的/run/secrets/中的文件名称为redis_secret,指定UID和GID均为103,指定要挂载到服务的任务容器的/run/secrets/中的文件权限为0440(group-readable),但该redis服务没有访问my_other_secret的权限:

version: "3.9"
services:
  redis:
    image: redis:latest
    deploy:
      replicas: 1
    secrets:
      - source: my_secret
        target: redis_secret
        uid: '103'
        gid: '103'
        mode: 0440
secrets:
  my_secret:
    file: ./my_secret.txt
  my_other_secret:
    external: true

32.security_opt

为每个容器覆盖默认的标签(label)。例如配置标签中的用户名和角色名:

services:
  redis:
    ...
    security_opt:
      - label:user:USER
      - label:role:ROLE

使用docker stack deploy时的注意事项:在swarm mode下部署堆栈时,security_opt配置项将被忽略。

# docker inspect --format '{{.HostConfig.SecurityOpt}}' 02a534e927b2 
[label:user:USER label:role:ROLE label=disable]

33.stop_grace_period

指定在发送SIGKILL之前,如果容器无法处理SIGTERM或使用stop_signal指定的任何停止信号时,试图停止该容器所需要的等待时间。默认情况下,stop在发送SIGKILL之前等待10秒以退出容器。时间指定为duration。具体示例如下:

services:
  redis:
    ...
    stop_grace_period: 1m30s
# docker inspect --format '{{.Config.StopTimeout}}' 02010fce43b8
90

34.stop_signal

设置停止容器的信号。默认使用SIGTERM停止容器。例如指定SIGUSR1信号:

services:
  redis:
    ...
    stop_signal: SIGUSR1
# docker inspect --format '{{.Config.StopSignal}}' 24b883a4ca86
SIGUSR1

35.sysctls

在容器中设置的内核参数。可以使用数组或字典两种格式。例如指定连接数为1024和开启TCP的syncookies:

services:
  redis:
    ...
    sysctls:
      net.core.somaxconn: 1024
      net.ipv4.tcp_syncookies: 0
# docker inspect --format '{{.HostConfig.Sysctls}}' 2ac559f58bb2 
map[net.core.somaxconn:1024 net.ipv4.tcp_syncookies:0]

36.tmpfs

挂载一个临时文件系统到容器内部。可以是一个值或一个列表。例如
services:
redis:
...
tmpfs: /run

tmpfs:
  - /run
  - /tmp
# docker inspect --format '{{.HostConfig.Tmpfs}}' 2f3f969ca726 
map[/run:]

在容器内挂载一个临时文件系统。Size可以指定挂载的tmpfs大小,以字节为单位。默认情况下不受限制。例如:

services:
  redis:
    ...
    - type: tmpfs
      target: /app
      tmpfs:
        size: 1000

37.ulimits

覆盖容器的默认ulimit值。可以单一地将限制值设为一个整数,也可以将soft/hard限制指定为映射。例如,指定最大进程数为65535,指定文件句柄数,其中软限制为20000,系统硬限制为40000,软限制应用可以随时修改,不能超过硬限制,硬限制只能root用户提高:

services:
  redis:
    ...
    ulimits:
      nproc: 65535
      nofile:
        soft: 20000
        hard: 40000
            "Ulimits": [
                {
                    "Name": "nproc",
                    "Hard": 65535,
                    "Soft": 65535
                },
                {
                    "Name": "nofile",
                    "Hard": 40000,
                    "Soft": 20000
                }
            ],
# docker inspect --format '{{.HostConfig.Ulimits}}' c3d082140a07
[nproc=65535:65535 nofile=20000:40000]

38.userns_mode

指定用户命名空间模式。如果Docker守护进程配置了用户名称空间,则禁用此服务的用户名称空间。以下是使用主机上的用户命名空间的配置示例:

userns_mode: "host"
默认UsernsMode为null
# docker inspect --format '{{.HostConfig.UsernsMode}}' c3d082140a07
设置UsernsMode为host
# docker inspect --format '{{.HostConfig.UsernsMode}}' bf76418f4ab6
host

使用docker stack deploy时的注意事项:在swarm mode下部署堆栈时,userns_mode配置项将被忽略。

39.volumes

指定所挂载的主机路径或数据卷名称。支持short和long两种格式的语法。可以将主机路径作为单个服务的一部分进行挂载,而无需在顶层volumes配置项中定义。但是如果想要在多个服务之间重用数据卷,需要在顶层volumes配置项中定义一个数据卷名称。
在3版的配置文件格式中的变化:在顶层volumes配置项中定义了数据卷名称并从每个服务的volumes列表中引用了该数据卷。这将替代早期版本的Compose配置文件格式中的volumes_from配置项。

1)Long syntax

short语法使用通用的[SOURCE:]TARGET[:MODE]格式,SOURCE可以是主机路径或数据卷名称,TARGET为挂载数据卷的容器路径,MODE可以为ro只读模式或rw读写模式(默认)。可以在主机上挂载相对路径,该路径相对于正在使用的Compose配置文件的目录进行扩展,相对路径应始终以.或..开头。例如:

volumes:
  # 只指定一个路径,Docker会自动在创建一个数据卷(这个路径是容器内部的)
  # Just specify a path and let the Engine create a volume
  - /var/lib/mysql
  # 使用绝对路径挂载数据卷
  # Specify an absolute path mapping
  - /opt/data:/var/lib/mysql
  # 使用基于Compose配置文件的相对路径作为数据卷挂载到容器
  # Path on the host, relative to the Compose file
  - ./cache:/tmp/cache
  # 使用基于root用户的相对路径作为数据卷挂载到容器
  # User-relative path
  - ~/configs:/etc/configs/:ro
  # 使用已经存在命名的数据卷挂载到容器
  # Named volume
  - datavolume:/var/lib/mysql
2)Short syntax

long语法支持配置以下short语法中不支持的附加字段:
type:挂载类型,可以为volume、bind、tmpfs或npipe。
source:挂载源,在主机上用于绑定挂载的路径或定义在顶层volumes配置项中的数据卷名称。不适用于tmpfs挂载类型。
target:数据卷挂载在容器中的路径。
read_only:设置数据卷为只读。
bind:配置额外的bind选项。
propagation:用于绑定的传播模式。
volume:配置额外的volume选项。
nocopy:创建数据卷时禁止从容器复制数据。
tmpfs:配置额外的tmpfs选项。
size:tmpfs挂载的大小,以字节为单位。
consistency:挂载的一致性要求,可以为consistent、cached或delegated。其中consistent表示主机和容器具有相同视图。cached表示读取缓存,主机视图是权威的。delegated表示读写缓存,容器视图是权威的。

version: "3.9"
services:
  web:
    image: nginx:alpine
    ports:
      - "80:80"
    volumes:
      - type: volume
        source: mydata
        target: /data
        volume:
          nocopy: true
      - type: bind
        source: ./static
        target: /opt/app/static

networks:
  webnet:

volumes:
  mydata:
services:
  redis:
    ...
    volumes:
      - redis_vol:/data
      - ./redis.conf:/etc/redis/redis.conf
# docker inspect --format '{{.Config.Volumes}}' bf76418f4ab6
map[/data:{} /etc/redis/redis.conf:{}]
3)Volumes for services, swarms, and stack files

注意:当使用services、swarms和docker-stack.yml文件时,请记住,支持服务的任务(容器)可以部署在群组中的任何节点上,并且每次更新服务时,这可能是不同的节点。
在没有指定来源的命名卷的情况下,Docker会为支持服务的每个任务创建一个匿名卷。删除关联的容器后,匿名卷不会持久存在。
如果希望数据持久化,请使用命名卷和支持多主机的卷驱动程序,以便可以从任何节点访问数据。或者,对服务设置约束,以便将其任务部署在具有卷的节点上。

version: "3.9"
services:
  db:
    image: postgres:9.4
    volumes:
      - db-data:/var/lib/postgresql/data
    networks:
      - backend
    deploy:
      placement:
        constraints: [node.role == manager]
4)domainname, hostname, ipc, mac_address, privileged, read_only, shm_size, stdin_open, tty, user, working_dir

每一个都是一个单独的值,类似于docker run的对应值。请注意,mac_address是一个遗留选项。

user: postgresql
working_dir: /code

domainname: foo.com
hostname: foo
ipc: host
mac_address: 02:42:ac:11:65:43

privileged: true

read_only: true
shm_size: 64M
stdin_open: true
tty: true

参考URL

https://blog.csdn.net/weixin_67479400/article/details/125864700
https://github.com/docker/compose/releases
https://docs.docker.com/compose/compose-file/compose-versioning/
https://docs.docker.com/compose/compose-file/compose-file-v3/
https://blog.csdn.net/qq_27546717/article/details/125586553

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 206,968评论 6 482
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 88,601评论 2 382
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 153,220评论 0 344
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 55,416评论 1 279
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 64,425评论 5 374
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 49,144评论 1 285
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 38,432评论 3 401
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 37,088评论 0 261
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 43,586评论 1 300
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 36,028评论 2 325
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 38,137评论 1 334
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,783评论 4 324
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 39,343评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 30,333评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,559评论 1 262
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 45,595评论 2 355
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,901评论 2 345

推荐阅读更多精彩内容