UNPKG

compose-spec-schema

Version:

TypeScript type and JSON schema for `docker-compose.yml`

1,461 lines (1,088 loc) 82.5 kB
# The Compose Specification {:.no_toc} * ToC {:toc} ## Status of this document This document specifies the Compose file format used to define multi-containers applications. Distribution of this document is unlimited. The key words "MUST", "MUST NOT", "REQUIRED", "SHALL", "SHALL NOT", "SHOULD", "SHOULD NOT", "RECOMMENDED", "MAY", and "OPTIONAL" in this document are to be interpreted as described in [RFC 2119](https://tools.ietf.org/html/rfc2119). ### Requirements and optional attributes The Compose specification includes properties designed to target a local [OCI](https://opencontainers.org/) container runtime, exposing Linux kernel specific configuration options, but also some Windows container specific properties, as well as cloud platform features related to resource placement on a cluster, replicated application distribution and scalability. We acknowledge that no Compose implementation is expected to support **all** attributes, and that support for some properties is Platform dependent and can only be confirmed at runtime. The definition of a versioned schema to control the supported properties in a Compose file, established by the [docker-compose](https://github.com/docker/compose) tool where the Compose file format was designed, doesn't offer any guarantee to the end-user attributes will be actually implemented. The specification defines the expected configuration syntax and behaviour, but - until noted - supporting any of those is OPTIONAL. A Compose implementation to parse a Compose file using unsupported attributes SHOULD warn user. We recommend implementors to support those running modes: * default: warn user about unsupported attributes, but ignore them * strict: warn user about unsupported attributes and reject the compose file * loose: ignore unsupported attributes AND unknown attributes (that were not defined by the spec by the time implementation was created) ## The Compose application model The Compose specification allows one to define a platform-agnostic container based application. Such an application is designed as a set of containers which have to both run together with adequate shared resources and communication channels. Computing components of an application are defined as [Services](#Services-top-level-element). A Service is an abstract concept implemented on platforms by running the same container image (and configuration) one or more times. Services communicate with each other through [Networks](#Networks-top-level-element). In this specification, a Network is a platform capability abstraction to establish an IP route between containers within services connected together. Low-level, platform-specific networking options are grouped into the Network definition and MAY be partially implemented on some platforms. Services store and share persistent data into [Volumes](#Volumes-top-level-element). The specification describes such a persistent data as a high-level filesystem mount with global options. Actual platform-specific implementation details are grouped into the Volumes definition and MAY be partially implemented on some platforms. Some services require configuration data that is dependent on the runtime or platform. For this, the specification defines a dedicated concept: [Configs](#Configs-top-level-element). From a Service container point of view, Configs are comparable to Volumes, in that they are files mounted into the container. But the actual definition involves distinct platform resources and services, which are abstracted by this type. A [Secret](#Secrets-top-level-element) is a specific flavour of configuration data for sensitive data that SHOULD NOT be exposed without security considerations. Secrets are made available to services as files mounted into their containers, but the platform-specific resources to provide sensitive data are specific enough to deserve a distinct concept and definition within the Compose specification. Distinction within Volumes, Configs and Secret allows implementations to offer a comparable abstraction at service level, but cover the specific configuration of adequate platform resources for well identified data usages. A **Project** is an individual deployment of an application specification on a platform. A project's name is used to group resources together and isolate them from other applications or other installation of the same Compose specified application with distinct parameters. A Compose implementation creating resources on a platform MUST prefix resource names by project and set the label `com.docker.compose.project`. ### Illustrative example The following example illustrates Compose specification concepts with a concrete example application. The example is non-normative. Consider an application split into a frontend web application and a backend service. The frontend is configured at runtime with an HTTP configuration file managed by infrastructure, providing an external domain name, and an HTTPS server certificate injected by the platform's secured secret store. The backend stores data in a persistent volume. Both services communicate with each other on an isolated back-tier network, while frontend is also connected to a front-tier network and exposes port 443 for external usage. ``` (External user) --> 443 [frontend network] | +--------------------+ | frontend service |...ro...<HTTP configuration> | "webapp" |...ro...<server certificate> #secured +--------------------+ | [backend network] | +--------------------+ | backend service | r+w ___________________ | "database" |=======( persistent volume ) +--------------------+ \_________________/ ``` The example application is composed of the following parts: - 2 services, backed by Docker images: `webapp` and `database` - 1 secret (HTTPS certificate), injected into the frontend - 1 configuration (HTTP), injected into the frontend - 1 persistent volume, attached to the backend - 2 networks ```yml services: frontend: image: awesome/webapp ports: - "443:8043" networks: - front-tier - back-tier configs: - httpd-config secrets: - server-certificate backend: image: awesome/database volumes: - db-data:/etc/data networks: - back-tier volumes: db-data: driver: flocker driver_opts: size: "10GiB" configs: httpd-config: external: true secrets: server-certificate: external: true networks: # The presence of these objects is sufficient to define them front-tier: {} back-tier: {} ``` This example illustrates the distinction between volumes, configs and secrets. While all of them are all exposed to service containers as mounted files or directories, only a volume can be configured for read+write access. Secrets and configs are read-only. The volume configuration allows you to select a volume driver and pass driver options to tweak volume management according to the actual infrastructure. Configs and Secrets rely on platform services, and are declared `external` as they are not managed as part of the application lifecycle: the Compose implementation will use a platform-specific lookup mechanism to retrieve runtime values. ## Compose file The Compose file is a [YAML](http://yaml.org/) file defining [version](#version-top-level-element) (DEPRECATED), [services](#services-top-level-element) (REQUIRED), [networks](#networks-top-level-element), [volumes](#volumes-top-level-element), [configs](#configs-top-level-element) and [secrets](#secrets-top-level-element). The default path for a Compose file is `compose.yaml` (preferred) or `compose.yml` in working directory. Compose implementations SHOULD also support `docker-compose.yaml` and `docker-compose.yml` for backward compatibility. If both files exist, Compose implementations MUST prefer canonical `compose.yaml` one. Multiple Compose files can be combined together to define the application model. The combination of YAML files MUST be implemented by appending/overriding YAML elements based on Compose file order set by the user. Simple attributes and maps get overridden by the highest order Compose file, lists get merged by appending. Relative paths MUST be resolved based on the **first** Compose file's parent folder, whenever complimentary files being merged are hosted in other folders. As some Compose file elements can both be expressed as single strings or complex objects, merges MUST apply to the expanded form. ### Profiles Profiles allow to adjust the Compose application model for various usages and environments. A Compose implementation SHOULD allow the user to define a set of active profiles. The exact mechanism is implementation specific and MAY include command line flags, environment variables, etc. The Services top-level element supports a `profiles` attribute to define a list of named profiles. Services without a `profiles` attribute set MUST always be enabled. A service MUST be ignored by the Compose implementation when none of the listed `profiles` match the active ones, unless the service is explicitly targeted by a command. In that case its `profiles` MUST be added to the set of active profiles. All other top-level elements are not affected by `profiles` and are always active. References to other services (by `links`, `extends` or shared resource syntax `service:xxx`) MUST not automatically enable a component that would otherwise have been ignored by active profiles. Instead the Compose implementation MUST return an error. #### Illustrative example ```yaml services: foo: image: foo bar: image: bar profiles: - test baz: image: baz depends_on: - bar profiles: - test zot: image: zot depends_on: - bar profiles: - debug ``` - Compose application model parsed with no profile enabled only contains the `foo` service. - If profile `test` is enabled, model contains the services `bar` and `baz` which are enabled by the `test` profile and service `foo` which is always enabled. - If profile `debug` is enabled, model contains both `foo` and `zot` services, but not `bar` and `baz` and as such the model is invalid regarding the `depends_on` constraint of `zot`. - If profiles `debug` and `test` are enabled, model contains all services: `foo`, `bar`, `baz` and `zot`. - If Compose implementation is executed with `bar` as explicit service to run, it and the `test` profile will be active even if `test` profile is not enabled _by the user_. - If Compose implementation is executed with `baz` as explicit service to run, the service `baz` and the profile `test` will be active and `bar` will be pulled in by the `depends_on` constraint. - If Compose implementation is executed with `zot` as explicit service to run, again the model will be invalid regarding the `depends_on` constraint of `zot` since `zot` and `bar` have no common `profiles` listed. - If Compose implementation is executed with `zot` as explicit service to run and profile `test` enabled, profile `debug` is automatically enabled and service `bar` is pulled in as a dependency starting both services `zot` and `bar`. ## Version top-level element Top-level `version` property is defined by the specification for backward compatibility but is only informative. A Compose implementation SHOULD NOT use this version to select an exact schema to validate the Compose file, but prefer the most recent schema at the time it has been designed. Compose implementations SHOULD validate they can fully parse the Compose file. If some fields are unknown, typically because the Compose file was written with fields defined by a newer version of the specification, Compose implementations SHOULD warn the user. Compose implementations MAY offer options to ignore unknown fields (as defined by ["loose"](#Requirements-and-optional-attributes) mode). ## Services top-level element A Service is an abstract definition of a computing resource within an application which can be scaled/replaced independently from other components. Services are backed by a set of containers, run by the platform according to replication requirements and placement constraints. Being backed by containers, Services are defined by a Docker image and set of runtime arguments. All containers within a service are identically created with these arguments. A Compose file MUST declare a `services` root element as a map whose keys are string representations of service names, and whose values are service definitions. A service definition contains the configuration that is applied to each container started for that service. Each service MAY also include a Build section, which defines how to create the Docker image for the service. Compose implementations MAY support building docker images using this service definition. If not implemented the Build section SHOULD be ignored and the Compose file MUST still be considered valid. Build support is an OPTIONAL aspect of the Compose specification, and is described in detail [here](build.md) Each Service defines runtime constraints and requirements to run its containers. The `deploy` section groups these constraints and allows the platform to adjust the deployment strategy to best match containers' needs with available resources. Deploy support is an OPTIONAL aspect of the Compose specification, and is described in detail [here](deploy.md). If not implemented the Deploy section SHOULD be ignored and the Compose file MUST still be considered valid. ### deploy `deploy` specifies the configuration for the deployment and lifecycle of services, as defined [here](deploy.md). ### blkio_config `blkio_config` defines a set of configuration options to set block IO limits for this service. ```yml services: foo: image: busybox blkio_config: weight: 300 weight_device: - path: /dev/sda weight: 400 device_read_bps: - path: /dev/sdb rate: '12mb' device_read_iops: - path: /dev/sdb rate: 120 device_write_bps: - path: /dev/sdb rate: '1024k' device_write_iops: - path: /dev/sdb rate: 30 ``` #### device_read_bps, device_write_bps Set a limit in bytes per second for read / write operations on a given device. Each item in the list MUST have two keys: - `path`: defining the symbolic path to the affected device. - `rate`: either as an integer value representing the number of bytes or as a string expressing a byte value. #### device_read_iops, device_write_iops Set a limit in operations per second for read / write operations on a given device. Each item in the list MUST have two keys: - `path`: defining the symbolic path to the affected device. - `rate`: as an integer value representing the permitted number of operations per second. #### weight Modify the proportion of bandwidth allocated to this service relative to other services. Takes an integer value between 10 and 1000, with 500 being the default. #### weight_device Fine-tune bandwidth allocation by device. Each item in the list must have two keys: - `path`: defining the symbolic path to the affected device. - `weight`: an integer value between 10 and 1000. ### cpu_count `cpu_count` defines the number of usable CPUs for service container. ### cpu_percent `cpu_percent` defines the usable percentage of the available CPUs. ### cpu_shares `cpu_shares` defines (as integer value) service container relative CPU weight versus other containers. ### cpu_period `cpu_period` allow Compose implementations to configure CPU CFS (Completely Fair Scheduler) period when platform is based on Linux kernel. ### cpu_quota `cpu_quota` allow Compose implementations to configure CPU CFS (Completely Fair Scheduler) quota when platform is based on Linux kernel. ### cpu_rt_runtime `cpu_rt_runtime` configures CPU allocation parameters for platform with support for realtime scheduler. Can be either an integer value using microseconds as unit or a [duration](#specifying-durations). ```yml cpu_rt_runtime: '400ms' cpu_rt_runtime: 95000` ``` ### cpu_rt_period `cpu_rt_period` configures CPU allocation parameters for platform with support for realtime scheduler. Can be either an integer value using microseconds as unit or a [duration](#specifying-durations). ```yml cpu_rt_period: '1400us' cpu_rt_period: 11000` ``` ### cpus _DEPRECATED: use [deploy.reservations.cpus](deploy.md#cpus)_ `cpus` define the number of (potentially virtual) CPUs to allocate to service containers. This is a fractional number. `0.000` means no limit. ### cpuset `cpuset` defines the explicit CPUs in which to allow execution. Can be a range `0-3` or a list `0,1` ### build `build` specifies the build configuration for creating container image from source, as defined [here](build.md). ### cap_add `cap_add` specifies additional container [capabilities](http://man7.org/linux/man-pages/man7/capabilities.7.html) as strings. ``` cap_add: - ALL ``` ### cap_drop `cap_drop` specifies container [capabilities](http://man7.org/linux/man-pages/man7/capabilities.7.html) to drop as strings. ``` cap_drop: - NET_ADMIN - SYS_ADMIN ``` ### cgroup_parent `cgroup_parent` specifies an OPTIONAL parent [cgroup](http://man7.org/linux/man-pages/man7/cgroups.7.html) for the container. ``` cgroup_parent: m-executor-abcd ``` ### command `command` overrides the the default command declared by the container image (i.e. by Dockerfile's `CMD`). ``` command: bundle exec thin -p 3000 ``` The command can also be a list, in a manner similar to [Dockerfile](https://docs.docker.com/engine/reference/builder/#cmd): ``` command: [ "bundle", "exec", "thin", "-p", "3000" ] ``` ### configs `configs` grant access to configs on a per-service basis using the per-service `configs` configuration. Two different syntax variants are supported. Compose implementations MUST report an error if config doesn't exist on platform or isn't defined in the [`configs`](#configs-top-level-element) section of this Compose file. There are two syntaxes defined for configs. To remain compliant to this specification, an implementation MUST support both syntaxes. Implementations MUST allow use of both short and long syntaxes within the same document. #### Short syntax The short syntax variant only specifies the config name. This grants the container access to the config and mounts it at `/<config_name>` within the container. The source name and destination mount point are both set to the config name. The following example uses the short syntax to grant the `redis` service access to the `my_config` and `my_other_config` configs. The value of `my_config` is set to the contents of the file `./my_config.txt`, and `my_other_config` is defined as an external resource, which means that it has already been defined in the platform. If the external config does not exist, the deployment MUST fail. ```yml services: redis: image: redis:latest configs: - my_config configs: my_config: file: ./my_config.txt my_other_config: external: true ``` #### Long syntax The long syntax provides more granularity in how the config is created within the service's task containers. - `source`: The name of the config as it exists in the platform. - `target`: The path and name of the file to be mounted in the service's task containers. Defaults to `/<source>` if not specified. - `uid` and `gid`: The numeric UID or GID that owns the mounted config file within the service's task containers. Default value when not specified is USER running container. - `mode`: The [permissions](http://permissions-calculator.org/) for the file that is mounted within the service's task containers, in octal notation. Default value is world-readable (`0444`). Writable bit MUST be ignored. The executable bit can be set. The following example sets the name of `my_config` to `redis_config` within the container, sets the mode to `0440` (group-readable) and sets the user and group to `103`. The `redis` service does not have access to the `my_other_config` config. ```yml services: redis: image: redis:latest configs: - source: my_config target: /redis_config uid: "103" gid: "103" mode: 0440 configs: my_config: external: true my_other_config: external: true ``` You can grant a service access to multiple configs, and you can mix long and short syntax. ### container_name `container_name` is a string that specifies a custom container name, rather than a generated default name. ```yml container_name: my-web-container ``` Compose implementation MUST NOT scale a service beyond one container if the Compose file specifies a `container_name`. Attempting to do so MUST result in an error. If present, `container_name` SHOULD follow the regex format of `[a-zA-Z0-9][a-zA-Z0-9_.-]+` ### credential_spec `credential_spec` configures the credential spec for a managed service account. Compose implementations that support services using Windows containers MUST support `file:` and `registry:` protocols for credential_spec. Compose implementations MAY also support additional protocols for custom use-cases. The `credential_spec` must be in the format `file://<filename>` or `registry://<value-name>`. ```yml credential_spec: file: my-credential-spec.json ``` When using `registry:`, the credential spec is read from the Windows registry on the daemon's host. A registry value with the given name must be located in: HKLM\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Virtualization\Containers\CredentialSpecs The following example loads the credential spec from a value named `my-credential-spec` in the registry: ```yml credential_spec: registry: my-credential-spec ``` #### Example gMSA configuration When configuring a gMSA credential spec for a service, you only need to specify a credential spec with `config`, as shown in the following example: ```yml services: myservice: image: myimage:latest credential_spec: config: my_credential_spec configs: my_credentials_spec: file: ./my-credential-spec.json| ``` ### depends_on `depends_on` expresses startup and shutdown dependencies between services. #### Short syntax The short syntax variant only specifies service names of the dependencies. Service dependencies cause the following behaviors: - Compose implementations MUST create services in dependency order. In the following example, `db` and `redis` are created before `web`. - Compose implementations MUST remove services in dependency order. In the following example, `web` is removed before `db` and `redis`. Simple example: ```yml services: web: build: . depends_on: - db - redis redis: image: redis db: image: postgres ``` Compose implementations MUST guarantee dependency services have been started before starting a dependent service. Compose implementations MAY wait for dependency services to be "ready" before starting a dependent service. #### Long syntax The long form syntax enables the configuration of additional fields that can't be expressed in the short form. - `condition`: condition under which dependency is considered satisfied - `service_started`: is an equivalent of the short syntax described above - `service_healthy`: specifies that a dependency is expected to be "healthy" (as indicated by [healthcheck](#healthcheck)) before starting a dependent service. - `service_completed_successfully`: specifies that a dependency is expected to run to successful completion before starting a dependent service. Service dependencies cause the following behaviors: - Compose implementations MUST create services in dependency order. In the following example, `db` and `redis` are created before `web`. - Compose implementations MUST wait for healthchecks to pass on dependencies marked with `service_healthy`. In the following example, `db` is expected to be "healthy" before `web` is created. - Compose implementations MUST remove services in dependency order. In the following example, `web` is removed before `db` and `redis`. Simple example: ```yml services: web: build: . depends_on: db: condition: service_healthy redis: condition: service_started redis: image: redis db: image: postgres ``` Compose implementations MUST guarantee dependency services have been started before starting a dependent service. Compose implementations MUST guarantee dependency services marked with `service_healthy` are "healthy" before starting a dependent service. ### device_cgroup_rules `device_cgroup_rules` defines a list of device cgroup rules for this container. The format is the same format the Linux kernel specifies in the [Control Groups Device Whitelist Controller](https://www.kernel.org/doc/html/latest/admin-guide/cgroup-v1/devices.html). ```yml device_cgroup_rules: - 'c 1:3 mr' - 'a 7:* rmw' ``` ### devices `devices` defines a list of device mappings for created containers in the form of `HOST_PATH:CONTAINER_PATH[:CGROUP_PERMISSIONS]`. ```yml devices: - "/dev/ttyUSB0:/dev/ttyUSB0" - "/dev/sda:/dev/xvda:rwm" ``` ### dns `dns` defines custom DNS servers to set on the container network interface configuration. Can be a single value or a list. ```yml dns: 8.8.8.8 ``` ```yml dns: - 8.8.8.8 - 9.9.9.9 ``` ### dns_opt `dns_opt` list custom DNS options to be passed to the container’s DNS resolver (`/etc/resolv.conf` file on Linux). ```yml dns_opt: - use-vc - no-tld-query ``` ### dns_search `dns` defines custom DNS search domains to set on container network interface configuration. Can be a single value or a list. ```yml dns_search: example.com ``` ```yml dns_search: - dc1.example.com - dc2.example.com ``` ### domainname `domainname` declares a custom domain name to use for the service container. MUST be a valid RFC 1123 hostname. ### entrypoint `entrypoint` overrides the default entrypoint for the Docker image (i.e. `ENTRYPOINT` set by Dockerfile). Compose implementations MUST clear out any default command on the Docker image - both `ENTRYPOINT` and `CMD` instruction in the Dockerfile - when `entrypoint` is configured by a Compose file. If [`command`](#command) is also set, it is used as parameter to `entrypoint` as a replacement for Docker image's `CMD` ```yml entrypoint: /code/entrypoint.sh ``` The entrypoint can also be a list, in a manner similar to [Dockerfile](https://docs.docker.com/engine/reference/builder/#cmd): ```yml entrypoint: - php - -d - zend_extension=/usr/local/lib/php/extensions/no-debug-non-zts-20100525/xdebug.so - -d - memory_limit=-1 - vendor/bin/phpunit ``` ### env_file `env_file` adds environment variables to the container based on file content. ```yml env_file: .env ``` `env_file` can also be a list. The files in the list MUST be processed from the top down. For the same variable specified in two env files, the value from the last file in the list MUST stand. ```yml env_file: - ./a.env - ./b.env ``` Relative path MUST be resolved from the Compose file's parent folder. As absolute paths prevent the Compose file from being portable, Compose implementations SHOULD warn users when such a path is used to set `env_file`. Environment variables declared in the [environment](#environment) section MUST override these values – this holds true even if those values are empty or undefined. #### Env_file format Each line in an env file MUST be in `VAR[=[VAL]]` format. Lines beginning with `#` MUST be ignored. Blank lines MUST also be ignored. The value of `VAL` is used as a raw string and not modified at all. If the value is surrounded by quotes (as is often the case for shell variables), the quotes MUST be **included** in the value passed to containers created by the Compose implementation. `VAL` MAY be omitted, in such cases the variable value is empty string. `=VAL` MAY be omitted, in such cases the variable is **unset**. ```bash # Set Rails/Rack environment RACK_ENV=development VAR="quoted" ``` ### environment `environment` defines environment variables set in the container. `environment` can use either an array or a map. Any boolean values; true, false, yes, no, SHOULD be enclosed in quotes to ensure they are not converted to True or False by the YAML parser. Environment variables MAY be declared by a single key (no value to equals sign). In such a case Compose implementations SHOULD rely on some user interaction to resolve the value. If they do not, the variable is unset and will be removed from the service container environment. Map syntax: ```yml environment: RACK_ENV: development SHOW: "true" USER_INPUT: ``` Array syntax: ```yml environment: - RACK_ENV=development - SHOW=true - USER_INPUT ``` When both `env_file` and `environment` are set for a service, values set by `environment` have precedence. ### expose `expose` defines the ports that Compose implementations MUST expose from container. These ports MUST be accessible to linked services and SHOULD NOT be published to the host machine. Only the internal container ports can be specified. ```yml expose: - "3000" - "8000" ``` ### extends Extend another service, in the current file or another, optionally overriding configuration. You can use `extends` on any service together with other configuration keys. The `extends` value MUST be a mapping defined with a required `service` and an optional `file` key. ```yaml extends: file: common.yml service: webapp ``` If supported Compose implementations MUST process `extends` in the following way: - `service` defines the name of the service being referenced as a base, for example `web` or `database`. - `file` is the location of a Compose configuration file defining that service. #### Restrictions The following restrictions apply to the service being referenced: - Services that have dependencies on other services cannot be used as a base. Therefore, any key that introduces a dependency on another service is incompatible with `extends`. The non-exhaustive list of such keys is: `links`, `volumes_from`, `container` mode (in `ipc`, `pid`, `network_mode` and `net`), `service` mode (in `ipc`, `pid` and `network_mode`), `depends_on`. - Services cannot have circular references with `extends` Compose implementations MUST return an error in all of these cases. #### Finding referenced service `file` value can be: - Not present. This indicates that another service within the same Compose file is being referenced. - File path, which can be either: - Relative path. This path is considered as relative to the location of the main Compose file. - Absolute path. Service denoted by `service` MUST be present in the identified referenced Compose file. Compose implementations MUST return an error if: - Service denoted by `service` was not found - Compose file denoted by `file` was not found #### Merging service definitions Two service definitions (_main_ one in the current Compose file and _referenced_ one specified by `extends`) MUST be merged in the following way: - Mappings: keys in mappings of _main_ service definition override keys in mappings of _referenced_ service definition. Keys that aren't overridden are included as is. - Sequences: items are combined together into an new sequence. Order of elements is preserved with the _referenced_ items coming first and _main_ items after. - Scalars: keys in _main_ service definition take precedence over keys in the _referenced_ one. ##### Mappings The following keys should be treated as mappings: `build.args`, `build.labels`, `build.extra_hosts`, `deploy.labels`, `deploy.update_config`, `deploy.rollback_config`, `deploy.restart_policy`, `deploy.resources.limits`, `environment`, `healthcheck`, `labels`, `logging.options`, `sysctls`, `storage_opt`, `extra_hosts`, `ulimits`. One exception that applies to `healthcheck` is that _main_ mapping cannot specify `disable: true` unless _referenced_ mapping also specifies `disable: true`. Compose implementations MUST return an error in this case. For example, the input below: ```yaml services: common: image: busybox environment: TZ: utc PORT: 80 cli: extends: service: common environment: PORT: 8080 ``` Produces the following configuration for the `cli` service. The same output is produced if array syntax is used. ```yaml environment: PORT: 8080 TZ: utc image: busybox ``` Items under `blkio_config.device_read_bps`, `blkio_config.device_read_iops`, `blkio_config.device_write_bps`, `blkio_config.device_write_iops`, `devices` and `volumes` are also treated as mappings where key is the target path inside the container. For example, the input below: ```yaml services: common: image: busybox volumes: - common-volume:/var/lib/backup/data:rw cli: extends: service: common volumes: - cli-volume:/var/lib/backup/data:ro ``` Produces the following configuration for the `cli` service. Note that mounted path now points to the new volume name and `ro` flag was applied. ```yaml image: busybox volumes: - cli-volume:/var/lib/backup/data:ro ``` If _referenced_ service definition contains `extends` mapping, the items under it are simply copied into the new _merged_ definition. Merging process is then kicked off again until no `extends` keys are remaining. For example, the input below: ```yaml services: base: image: busybox user: root common: image: busybox extends: service: base cli: extends: service: common ``` Produces the following configuration for the `cli` service. Here, `cli` services gets `user` key from `common` service, which in turn gets this key from `base` service. ```yaml image: busybox user: root ``` ##### Sequences The following keys should be treated as sequences: `cap_add`, `cap_drop`, `configs`, `deploy.placement.constraints`, `deploy.placement.preferences`, `deploy.reservations.generic_resources`, `device_cgroup_rules`, `expose`, `external_links`, `ports`, `secrets`, `security_opt`. Any duplicates resulting from the merge are removed so that the sequence only contains unique elements. For example, the input below: ```yaml services: common: image: busybox security_opt: - label:role:ROLE cli: extends: service: common security_opt: - label:user:USER ``` Produces the following configuration for the `cli` service. ```yaml image: busybox security_opt: - label:role:ROLE - label:user:USER ``` In case list syntax is used, the following keys should also be treated as sequences: `dns`, `dns_search`, `env_file`, `tmpfs`. Unlike sequence fields mentioned above, duplicates resulting from the merge are not removed. ##### Scalars Any other allowed keys in the service definition should be treated as scalars. ### external_links `external_links` link service containers to services managed outside this Compose application. `external_links` define the name of an existing service to retrieve using the platform lookup mechanism. An alias of the form `SERVICE:ALIAS` can be specified. ```yml external_links: - redis - database:mysql - database:postgresql ``` ### extra_hosts `extra_hosts` adds hostname mappings to the container network interface configuration (`/etc/hosts` for Linux). Values MUST set hostname and IP address for additional hosts in the form of `HOSTNAME:IP`. ```yml extra_hosts: - "somehost:162.242.195.82" - "otherhost:50.31.209.229" ``` Compose implementations MUST create matching entry with the IP address and hostname in the container's network configuration, which means for Linux `/etc/hosts` will get extra lines: ``` 162.242.195.82 somehost 50.31.209.229 otherhost ``` ### group_add `group_add` specifies additional groups (by name or number) which the user inside the container MUST be a member of. An example of where this is useful is when multiple containers (running as different users) need to all read or write the same file on a shared volume. That file can be owned by a group shared by all the containers, and specified in `group_add`. ```yml services: myservice: image: alpine group_add: - mail ``` Running `id` inside the created container MUST show that the user belongs to the `mail` group, which would not have been the case if `group_add` were not declared. ### healthcheck `healthcheck` declares a check that's run to determine whether or not containers for this service are "healthy". This overrides [HEALTHCHECK Dockerfile instruction](https://docs.docker.com/engine/reference/builder/#healthcheck) set by the service's Docker image. ```yml healthcheck: test: ["CMD", "curl", "-f", "http://localhost"] interval: 1m30s timeout: 10s retries: 3 start_period: 40s ``` `interval`, `timeout` and `start_period` are [specified as durations](#specifying-durations). `test` defines the command the Compose implementation will run to check container health. It can be either a string or a list. If it's a list, the first item must be either `NONE`, `CMD` or `CMD-SHELL`. If it's a string, it's equivalent to specifying `CMD-SHELL` followed by that string. ```yml # Hit the local web app test: ["CMD", "curl", "-f", "http://localhost"] ``` Using `CMD-SHELL` will run the command configured as a string using the container's default shell (`/bin/sh` for Linux). Both forms below are equivalent: ```yml test: ["CMD-SHELL", "curl -f http://localhost || exit 1"] ``` ```yml test: curl -f https://localhost || exit 1 ``` `NONE` disable the healthcheck, and is mostly useful to disable Healthcheck set by image. Alternatively the healthcheck set by the image can be disabled by setting `disable: true`: ```yml healthcheck: disable: true ``` ### hostname `hostname` declares a custom host name to use for the service container. MUST be a valid RFC 1123 hostname. ### image `image` specifies the image to start the container from. Image MUST follow the Open Container Specification [addressable image format](https://github.com/opencontainers/org/blob/master/docs/docs/introduction/digests.md), as `[<registry>/][<project>/]<image>[:<tag>|@<digest>]`. ```yml image: redis image: redis:5 image: redis@sha256:0ed5d5928d4737458944eb604cc8509e245c3e19d02ad83935398bc4b991aac7 image: library/redis image: docker.io/library/redis image: my_private.registry:5000/redis ``` If the image does not exist on the platform, Compose implementations MUST attempt to pull it based on the `pull_policy`. Compose implementations with build support MAY offer alternative options for the end user to control precedence of pull over building the image from source, however pulling the image MUST be the default behavior. `image` MAY be omitted from a Compose file as long as a `build` section is declared. Compose implementations without build support MUST fail when `image` is missing from the Compose file. ### init `init` run an init process (PID 1) inside the container that forwards signals and reaps processes. Set this option to `true` to enable this feature for the service. ```yml services: web: image: alpine:latest init: true ``` The init binary that is used is platform specific. ### ipc `ipc` configures the IPC isolation mode set by service container. Available values are platform specific, but Compose specification defines specific values which MUST be implemented as described if supported: - `shareable` which gives the container own private IPC namespace, with a possibility to share it with other containers. - `service:{name}` which makes the container join another (`shareable`) container's IPC namespace. ```yml ipc: "shareable" ipc: "service:[service name]" ``` ### isolation `isolation` specifies a container’s isolation technology. Supported values are platform-specific. ### labels `labels` add metadata to containers. You can use either an array or a map. It's recommended that you use reverse-DNS notation to prevent your labels from conflicting with those used by other software. ```yml labels: com.example.description: "Accounting webapp" com.example.department: "Finance" com.example.label-with-empty-value: "" ``` ```yml labels: - "com.example.description=Accounting webapp" - "com.example.department=Finance" - "com.example.label-with-empty-value" ``` Compose implementations MUST create containers with canonical labels: - `com.docker.compose.project` set on all resources created by Compose implementation to the user project name - `com.docker.compose.service` set on service containers with service name as defined in the Compose file The `com.docker.compose` label prefix is reserved. Specifying labels with this prefix in the Compose file MUST result in a runtime error. ### links `links` defines a network link to containers in another service. Either specify both the service name and a link alias (`SERVICE:ALIAS`), or just the service name. ```yml web: links: - db - db:database - redis ``` Containers for the linked service MUST be reachable at a hostname identical to the alias, or the service name if no alias was specified. Links are not required to enable services to communicate - when no specific network configuration is set, any service MUST be able to reach any other service at that service’s name on the `default` network. If services do declare networks they are attached to, `links` SHOULD NOT override the network configuration and services not attached to a shared network SHOULD NOT be able to communicate. Compose implementations MAY NOT warn the user about this configuration mismatch. Links also express implicit dependency between services in the same way as [depends_on](#depends_on), so they determine the order of service startup. ### logging `logging` defines the logging configuration for the service. ```yml logging: driver: syslog options: syslog-address: "tcp://192.168.0.42:123" ``` The `driver` name specifies a logging driver for the service's containers. The default and available values are platform specific. Driver specific options can be set with `options` as key-value pairs. ### network_mode `network_mode` set service containers network mode. Available values are platform specific, but Compose specification define specific values which MUST be implemented as described if supported: - `none` which disable all container networking - `host` which gives the container raw access to host's network interface - `service:{name}` which gives the containers access to the specified service only ```yml network_mode: "host" network_mode: "none" network_mode: "service:[service name]" ``` ### networks `networks` defines the networks that service containers are attached to, referencing entries under the [top-level `networks` key](#networks-top-level-element). ```yml services: some-service: networks: - some-network - other-network ``` #### aliases `aliases` declares alternative hostnames for this service on the network. Other containers on the same network can use either the service name or this alias to connect to one of the service's containers. Since `aliases` are network-scoped, the same service can have different aliases on different networks. > **Note**: A network-wide alias can be shared by multiple containers, and even by multiple services. > If it is, then exactly which container the name resolves to is not guaranteed. The general format is shown here: ```yml services: some-service: networks: some-network: aliases: - alias1 - alias3 other-network: aliases: - alias2 ``` In the example below, service `frontend` will be able to reach the `backend` service at the hostname `backend` or `database` on the `back-tier` network, and service `monitoring` will be able to reach same `backend` service at `db` or `mysql` on the `admin` network. ```yml services: frontend: image: awesome/webapp networks: - front-tier - back-tier monitoring: image: awesome/monitoring networks: - admin backend: image: awesome/backend networks: back-tier: aliases: - database admin: aliases: - mysql networks: front-tier: back-tier: admin: ``` #### ipv4_address, ipv6_address Specify a static IP address for containers for this service when joining the network. The corresponding network configuration in the [top-level networks section](#networks) MUST have an `ipam` block with subnet configurations covering each static address. ```yml services: frontend: image: awesome/webapp networks: front-tier: ipv4_address: 172.16.238.10 ipv6_address: 2001:3984:3989::10 networks: front-tier: ipam: driver: default config: - subnet: "172.16.238.0/24" - subnet: "2001:3984:3989::/64" ``` #### link_local_ips `link_local_ips` specifies a list of link-local IPs. Link-local IPs are special IPs which belong to a well known subnet and are purely managed by the operator, usually dependent on the architecture where they are deployed. Implementation is Platform specific. Example: ```yaml services: app: image: busybox command: top networks: app_net: link_local_ips: - 57.123.22.11 - 57.123.22.13 networks: app_net: driver: bridge ``` #### priority `priority` indicates in which order Compose implementation SHOULD connect the service’s containers to its networks. If unspecified, the default value is 0. In the following example, the app service connects to app_net_1 first as it has the highest priority. It then connects to app_net_3, then app_net_2, which uses the default priority value of 0. ```yaml services: app: image: busybox command: top networks: app_net_1: priority: 1000 app_net_2: app_net_3: priority: 100 networks: app_net_1: app_net_2: app_net_3: ``` ### mac_address `mac_address` sets a MAC address for service container. ### mem_limit _DEPRECATED: use [deploy.limits.memory](deploy.md#memory)_ ### mem_reservation _DEPRECATED: use [deploy.reservations.memory](deploy.md#memory)_ ### mem_swappiness `mem_swappiness` defines as a percentage (a value between 0 and 100) for the host kernel to swap out anonymous memory pages used by a container. - a value of 0 turns off anonymous page swapping. - a value of 100 sets all anonymous pages as swappable. Default value is platform specific. ### memswap_limit `memswap_limit` defines the amount of memory container is allowed to swap to disk. This is a modifier attribute that only has meaning if `memory` is also set. Using swap allows the container to write excess memory requirements to disk when the container has exhausted all the memory that is available to it. There is a performance penalty for applications that swap memory to disk often. - If `memswap_limit` is set to a positive integer, then both `memory` and `memswap_limit` MUST be set. `memswap_limit` represents the total amount of memory and swap that can be used, and `memory` controls the amount used by non-swap memory. So if `memory`="300m" and `memswap_limit`="1g", the container can use 300m of memory and 700m (1g - 300m) swap. - If `memswap_limit` is set to 0, the setting MUST be ignored, and the value is treated as unset. - If `memswap_limit` is set to the same value as `memory`, and `memory` is set to a positive integer, the container does not have access to swap. See Prevent a container from using swap. - If `memswap_limit` is unset, and `memory` is set, the container can use as much swap as the `memory` setting, if the host container has swap memory configured. For instance, if `memory`="300m" and `memswap_limit` is not set, the container can use 600m in total of memory and swap. - If `memswap_limit` is explicitly set to -1, the container is allowed to use unlimited swap, up to the amount available on the host system. ### oom_kill_disable If `oom_kill_disable` is set Compose implementation MUST configure the platform so it won't kill the container in case of memory starvation. ### oom_score_adj `oom_score_adj` tunes the preference for containers to be killed by platform in case of memory starvation. Value MUST be within [-1000,1000] range. ### pid `pid` sets the PID mode for container created by the Compose implementation. Supported values are platform specific. ### pids_limit `pids_limit` tunes a container’s PIDs limit. Set to -1 for unlimited PIDs. ```yml pids_limit: 10 ``` ### platform `platform` defines the target platform containers for this service will run on, using the `os[/arch[/variant]]` syntax. Compose implementation MUST use this attribute when declared to determine which version of the image will be pulled and/or on which platform the service’s build will be performed. ```yml platform: osx platform: windows/amd64 platform: linux/arm64/v8 ``` ### ports Exposes container ports. Port mapping MUST NOT be used with `network_mode: host` and doing so MUST result in a runtime error. #### Short syntax The short syntax is a colon-separated string to set host IP, host port and container port in the form: `[HOST:]CONTAINER[/PROTOCOL]` where: - `HOST` is `[IP:](port | range)` - `CONTAINER` is `port | range` - `PROTOCOL` to restrict port to specified protocol. `tcp` and `udp` values are defined by the specification, Co