diff --git a/.gitignore b/.gitignore index 0bbcc0e0..6922b966 100644 --- a/.gitignore +++ b/.gitignore @@ -1 +1,2 @@ docs/*.json +_site/ diff --git a/Gemfile b/Gemfile new file mode 100644 index 00000000..310782bb --- /dev/null +++ b/Gemfile @@ -0,0 +1,2 @@ +source "https://rubygems.org" +gem "github-pages", "~> 212", group: :jekyll_plugins diff --git a/Gemfile.lock b/Gemfile.lock new file mode 100644 index 00000000..e0387e71 --- /dev/null +++ b/Gemfile.lock @@ -0,0 +1,263 @@ +GEM + remote: https://rubygems.org/ + specs: + activesupport (6.0.3.5) + concurrent-ruby (~> 1.0, >= 1.0.2) + i18n (>= 0.7, < 2) + minitest (~> 5.1) + tzinfo (~> 1.1) + zeitwerk (~> 2.2, >= 2.2.2) + addressable (2.8.0) + public_suffix (>= 2.0.2, < 5.0) + coffee-script (2.4.1) + coffee-script-source + execjs + coffee-script-source (1.11.1) + colorator (1.1.0) + commonmarker (0.17.13) + ruby-enum (~> 0.5) + concurrent-ruby (1.1.8) + dnsruby (1.61.5) + simpleidn (~> 0.1) + em-websocket (0.5.2) + eventmachine (>= 0.12.9) + http_parser.rb (~> 0.6.0) + ethon (0.12.0) + ffi (>= 1.3.0) + eventmachine (1.2.7) + execjs (2.7.0) + faraday (1.3.0) + faraday-net_http (~> 1.0) + multipart-post (>= 1.2, < 3) + ruby2_keywords + faraday-net_http (1.0.1) + ffi (1.14.2) + forwardable-extended (2.6.0) + gemoji (3.0.1) + github-pages (212) + github-pages-health-check (= 1.17.0) + jekyll (= 3.9.0) + jekyll-avatar (= 0.7.0) + jekyll-coffeescript (= 1.1.1) + jekyll-commonmark-ghpages (= 0.1.6) + jekyll-default-layout (= 0.1.4) + jekyll-feed (= 0.15.1) + jekyll-gist (= 1.5.0) + jekyll-github-metadata (= 2.13.0) + jekyll-mentions (= 1.6.0) + jekyll-optional-front-matter (= 0.3.2) + jekyll-paginate (= 1.1.0) + jekyll-readme-index (= 0.3.0) + jekyll-redirect-from (= 0.16.0) + jekyll-relative-links (= 0.6.1) + jekyll-remote-theme (= 0.4.2) + jekyll-sass-converter (= 1.5.2) + jekyll-seo-tag (= 2.7.1) + jekyll-sitemap (= 1.4.0) + jekyll-swiss (= 1.0.0) + jekyll-theme-architect (= 0.1.1) + jekyll-theme-cayman (= 0.1.1) + jekyll-theme-dinky (= 0.1.1) + jekyll-theme-hacker (= 0.1.2) + jekyll-theme-leap-day (= 0.1.1) + jekyll-theme-merlot (= 0.1.1) + jekyll-theme-midnight (= 0.1.1) + jekyll-theme-minimal (= 0.1.1) + jekyll-theme-modernist (= 0.1.1) + jekyll-theme-primer (= 0.5.4) + jekyll-theme-slate (= 0.1.1) + jekyll-theme-tactile (= 0.1.1) + jekyll-theme-time-machine (= 0.1.1) + jekyll-titles-from-headings (= 0.5.3) + jemoji (= 0.12.0) + kramdown (= 2.3.0) + kramdown-parser-gfm (= 1.1.0) + liquid (= 4.0.3) + mercenary (~> 0.3) + minima (= 2.5.1) + nokogiri (>= 1.10.4, < 2.0) + rouge (= 3.26.0) + terminal-table (~> 1.4) + github-pages-health-check (1.17.0) + addressable (~> 2.3) + dnsruby (~> 1.60) + octokit (~> 4.0) + public_suffix (>= 2.0.2, < 5.0) + typhoeus (~> 1.3) + html-pipeline (2.14.0) + activesupport (>= 2) + nokogiri (>= 1.4) + http_parser.rb (0.6.0) + i18n (0.9.5) + concurrent-ruby (~> 1.0) + jekyll (3.9.0) + addressable (~> 2.4) + colorator (~> 1.0) + em-websocket (~> 0.5) + i18n (~> 0.7) + jekyll-sass-converter (~> 1.0) + jekyll-watch (~> 2.0) + kramdown (>= 1.17, < 3) + liquid (~> 4.0) + mercenary (~> 0.3.3) + pathutil (~> 0.9) + rouge (>= 1.7, < 4) + safe_yaml (~> 1.0) + jekyll-avatar (0.7.0) + jekyll (>= 3.0, < 5.0) + jekyll-coffeescript (1.1.1) + coffee-script (~> 2.2) + coffee-script-source (~> 1.11.1) + jekyll-commonmark (1.3.1) + commonmarker (~> 0.14) + jekyll (>= 3.7, < 5.0) + jekyll-commonmark-ghpages (0.1.6) + commonmarker (~> 0.17.6) + jekyll-commonmark (~> 1.2) + rouge (>= 2.0, < 4.0) + jekyll-default-layout (0.1.4) + jekyll (~> 3.0) + jekyll-feed (0.15.1) + jekyll (>= 3.7, < 5.0) + jekyll-gist (1.5.0) + octokit (~> 4.2) + jekyll-github-metadata (2.13.0) + jekyll (>= 3.4, < 5.0) + octokit (~> 4.0, != 4.4.0) + jekyll-mentions (1.6.0) + html-pipeline (~> 2.3) + jekyll (>= 3.7, < 5.0) + jekyll-optional-front-matter (0.3.2) + jekyll (>= 3.0, < 5.0) + jekyll-paginate (1.1.0) + jekyll-readme-index (0.3.0) + jekyll (>= 3.0, < 5.0) + jekyll-redirect-from (0.16.0) + jekyll (>= 3.3, < 5.0) + jekyll-relative-links (0.6.1) + jekyll (>= 3.3, < 5.0) + jekyll-remote-theme (0.4.2) + addressable (~> 2.0) + jekyll (>= 3.5, < 5.0) + jekyll-sass-converter (>= 1.0, <= 3.0.0, != 2.0.0) + rubyzip (>= 1.3.0, < 3.0) + jekyll-sass-converter (1.5.2) + sass (~> 3.4) + jekyll-seo-tag (2.7.1) + jekyll (>= 3.8, < 5.0) + jekyll-sitemap (1.4.0) + jekyll (>= 3.7, < 5.0) + jekyll-swiss (1.0.0) + jekyll-theme-architect (0.1.1) + jekyll (~> 3.5) + jekyll-seo-tag (~> 2.0) + jekyll-theme-cayman (0.1.1) + jekyll (~> 3.5) + jekyll-seo-tag (~> 2.0) + jekyll-theme-dinky (0.1.1) + jekyll (~> 3.5) + jekyll-seo-tag (~> 2.0) + jekyll-theme-hacker (0.1.2) + jekyll (> 3.5, < 5.0) + jekyll-seo-tag (~> 2.0) + jekyll-theme-leap-day (0.1.1) + jekyll (~> 3.5) + jekyll-seo-tag (~> 2.0) + jekyll-theme-merlot (0.1.1) + jekyll (~> 3.5) + jekyll-seo-tag (~> 2.0) + jekyll-theme-midnight (0.1.1) + jekyll (~> 3.5) + jekyll-seo-tag (~> 2.0) + jekyll-theme-minimal (0.1.1) + jekyll (~> 3.5) + jekyll-seo-tag (~> 2.0) + jekyll-theme-modernist (0.1.1) + jekyll (~> 3.5) + jekyll-seo-tag (~> 2.0) + jekyll-theme-primer (0.5.4) + jekyll (> 3.5, < 5.0) + jekyll-github-metadata (~> 2.9) + jekyll-seo-tag (~> 2.0) + jekyll-theme-slate (0.1.1) + jekyll (~> 3.5) + jekyll-seo-tag (~> 2.0) + jekyll-theme-tactile (0.1.1) + jekyll (~> 3.5) + jekyll-seo-tag (~> 2.0) + jekyll-theme-time-machine (0.1.1) + jekyll (~> 3.5) + jekyll-seo-tag (~> 2.0) + jekyll-titles-from-headings (0.5.3) + jekyll (>= 3.3, < 5.0) + jekyll-watch (2.2.1) + listen (~> 3.0) + jemoji (0.12.0) + gemoji (~> 3.0) + html-pipeline (~> 2.2) + jekyll (>= 3.0, < 5.0) + kramdown (2.3.0) + rexml + kramdown-parser-gfm (1.1.0) + kramdown (~> 2.0) + liquid (4.0.3) + listen (3.4.1) + rb-fsevent (~> 0.10, >= 0.10.3) + rb-inotify (~> 0.9, >= 0.9.10) + mercenary (0.3.6) + minima (2.5.1) + jekyll (>= 3.5, < 5.0) + jekyll-feed (~> 0.9) + jekyll-seo-tag (~> 2.1) + minitest (5.14.4) + multipart-post (2.1.1) + nokogiri (1.13.6-x86_64-linux) + racc (~> 1.4) + octokit (4.20.0) + faraday (>= 0.9) + sawyer (~> 0.8.0, >= 0.5.3) + pathutil (0.16.2) + forwardable-extended (~> 2.6) + public_suffix (4.0.6) + racc (1.6.0) + rb-fsevent (0.10.4) + rb-inotify (0.10.1) + ffi (~> 1.0) + rexml (3.2.5) + rouge (3.26.0) + ruby-enum (0.9.0) + i18n + ruby2_keywords (0.0.4) + rubyzip (2.3.0) + safe_yaml (1.0.5) + sass (3.7.4) + sass-listen (~> 4.0.0) + sass-listen (4.0.0) + rb-fsevent (~> 0.9, >= 0.9.4) + rb-inotify (~> 0.9, >= 0.9.7) + sawyer (0.8.2) + addressable (>= 2.3.5) + faraday (> 0.8, < 2.0) + simpleidn (0.2.1) + unf (~> 0.1.4) + terminal-table (1.8.0) + unicode-display_width (~> 1.1, >= 1.1.1) + thread_safe (0.3.6) + typhoeus (1.4.0) + ethon (>= 0.9.0) + tzinfo (1.2.10) + thread_safe (~> 0.1) + unf (0.1.4) + unf_ext + unf_ext (0.0.7.7) + unicode-display_width (1.7.0) + zeitwerk (2.4.2) + +PLATFORMS + x86_64-linux + +DEPENDENCIES + github-pages (~> 212) + +BUNDLED WITH + 2.2.11 diff --git a/OWNERS.md b/OWNERS.md index f8133423..494a017c 100644 --- a/OWNERS.md +++ b/OWNERS.md @@ -2,5 +2,6 @@ maintainers: - ndeloof - hangyan - justincormack -- kohidave - EricHripko +- ulyssessouza +- glours diff --git a/README.md b/README.md index 3a1044f7..94e3385f 100644 --- a/README.md +++ b/README.md @@ -1,18 +1,12 @@ # Compose Specification +{:.no_toc} The Compose specification establishes a standard for the definition of multi-container platform-agnostic applications. The specification can be found [here](spec.md). - - -## Table of Contents - -Additional documentation about how this group operates: -* [Governance](GOVERNANCE.md) -* [Contribution Guidelines](CONTRIBUTING.md) -* [Implementations](#Implementations) -* [Releases](https://github.com/docker/compose-spec/releases) +* ToC +{:toc} ## Use cases @@ -36,10 +30,9 @@ APIs to manage networking services, container deployments and their lifecycles. While this offers flexibility to address many operator use cases, it makes simple use cases, like the developer use case, more complicated to express than they need to be. Projects like [Kompose](https://github.com/kubernetes/kompose) -and [Compose on Kubernetes](https://github.com/docker/compose-on-kubernetes) -show how the simpler Compose model can be translated into Kubernetes API -payloads and make the Compose file the source of truth for development and -deployment. +or [Okteto Stacks](https://okteto.com/docs/reference/stacks) show how the +simpler Compose model can be translated into Kubernetes API payloads and make +the Compose file the source of truth for development and deployment. ### Cloud providers @@ -62,10 +55,14 @@ The specification and code is licensed under the Apache 2.0 license found in the ## Implementations -* [docker-compose](https://github.com/docker/compose) -* Docker CLI (`docker stack` command) -* [Compose on Kubernetes](https://github.com/docker/compose-on-kubernetes) +[Docker Compose](https://github.com/docker/compose) is the Reference Implementation of the Compose Specification. + +Compose Specification is also implemented by: + * [Kompose](https://github.com/kubernetes/kompose) +* [Nerdctl](https://github.com/containerd/nerdctl) +* [Okteto Stacks](https://okteto.com/docs/reference/stacks) +* [Docker Cloud Integrations](https://github.com/docker/compose-cli) | Metadata | | | -------- | ---------------: | diff --git a/_config.yml b/_config.yml new file mode 100644 index 00000000..725635a6 --- /dev/null +++ b/_config.yml @@ -0,0 +1,15 @@ +theme: jekyll-theme-cayman +title: Compose Specification +description: > + A specification for developer-centric application definition used in Cloud + Native Applications. +markdown: kramdown +defaults: + - scope: + path: "" + values: + layout: "page" +github: + repository_name: Compose Specification + owner_url: https://github.com/compose-spec/compose-spec/blob/master/OWNERS.md + owner_name: these members of the community diff --git a/_layouts/page.html b/_layouts/page.html new file mode 100644 index 00000000..148251b0 --- /dev/null +++ b/_layouts/page.html @@ -0,0 +1,8 @@ +--- +layout: default +--- + + + + +{{ content }} diff --git a/assets/css/style.scss b/assets/css/style.scss new file mode 100644 index 00000000..8a42d036 --- /dev/null +++ b/assets/css/style.scss @@ -0,0 +1,35 @@ +--- +--- + +@import "{{ site.theme }}"; + +.header { + position: absolute; + top: 0; + + box-sizing: border-box; + width: 64rem; + height: 64px; + padding: 8px; + background-image: url("{{ '/assets/images/compose_logo.png' | relative_url }}"); + background-repeat: no-repeat; + background-size: 322px 44px; + background-position: left center; +} + +.page-header { + margin-top: 64px; + padding: 1rem; + + .project-name { + display: none; + } + + .project-tagline { + margin: 0; + } + + .btn { + display: none; + } +} diff --git a/assets/images/compose_logo.png b/assets/images/compose_logo.png new file mode 100644 index 00000000..32ec6ec6 Binary files /dev/null and b/assets/images/compose_logo.png differ diff --git a/build.md b/build.md index 44c6b103..0ec2a748 100644 --- a/build.md +++ b/build.md @@ -1,11 +1,15 @@ # The Compose Specification - Build support +{:.no_toc} *Note:* Build is an OPTIONAL part of the Compose Specification +* ToC +{:toc} + ## Introduction Compose specification is a platform-neutral way to define multi-container applications. A Compose implementation -focussing on development use-case to run application on local machine will obviously also support (re)building +focusing on development use-case to run application on local machine will obviously also support (re)building application from sources. The Compose Build specification allows to define the build process within a Compose file in a portable way. @@ -60,8 +64,8 @@ services: backend: image: awesome/database build: - context: backend - dockerfile: ../backend.Dockerfile + context: backend + dockerfile: ../backend.Dockerfile custom: build: ~/custom @@ -69,9 +73,9 @@ services: When used to build service images from source, such a Compose file will create three docker images: -* `awesome/webapp` docker image is build using `webapp` sub-directory within Compose file parent folder as docker build context. Lack of a `Dockerfile` within this folder will throw an error. -* `awesome/database` docker image is build using `backend` sub-directory within Compose file parent folder. `backend.Dockerfile` file is used to define build steps, this file is searched relative to context path, which means for this sample `..` will resolve to Compose file parent folder, so `backend.Dockerfile` is a sibling file. -* a docker image is build using `custom` directory within user's HOME as docker context. Compose implementation warn user about non-portable path used to build image. +* `awesome/webapp` docker image is built using `webapp` sub-directory within Compose file parent folder as docker build context. Lack of a `Dockerfile` within this folder will throw an error. +* `awesome/database` docker image is built using `backend` sub-directory within Compose file parent folder. `backend.Dockerfile` file is used to define build steps, this file is searched relative to context path, which means for this sample `..` will resolve to Compose file parent folder, so `backend.Dockerfile` is a sibling file. +* a docker image is built using `custom` directory within user's HOME as docker context. Compose implementation warn user about non-portable path used to build image. On push, both `awesome/webapp` and `awesome/database` docker images are pushed to (default) registry. `custom` service image is skipped as no `Image` attribute is set and user is warned about this missing attribute. @@ -97,7 +101,7 @@ Alternatively `build` can be an object with fields defined as follow When the value supplied is a relative path, it MUST be interpreted as relative to the location of the Compose file. Compose implementations MUST warn user about absolute path used to define build context as those prevent Compose file -for being portable. +from being portable. ```yml build: @@ -108,7 +112,7 @@ build: `dockerfile` allows to set an alternate Dockerfile. A relative path MUST be resolved from the build context. Compose implementations MUST warn user about absolute path used to define Dockerfile as those prevent Compose file -for being portable. +from being portable. ```yml build: @@ -151,18 +155,78 @@ args: - GIT_COMMIT ``` +### ssh + +`ssh` defines SSH authentications that the image builder SHOULD use during image build (e.g., cloning private repository) + +`ssh` property syntax can be either: +* `default` - let the builder connect to the ssh-agent. +* `ID=path` - a key/value definition of an ID and the associated path. Can be either a [PEM](https://en.wikipedia.org/wiki/Privacy-Enhanced_Mail) file, or path to ssh-agent socket + +Simple `default` sample +```yaml +build: + context: . + ssh: + - default # mount the default ssh agent +``` +or +```yaml +build: + context: . + ssh: ["default"] # mount the default ssh agent +``` + +Using a custom id `myproject` with path to a local SSH key: +```yaml +build: + context: . + ssh: + - myproject=~/.ssh/myproject.pem +``` +Image builder can then rely on this to mount SSH key during build. +For illustration, [BuildKit extended syntax](https://github.com/compose-spec/compose-spec/pull/234/%5Bmoby/buildkit@master/frontend/dockerfile/docs/syntax.md#run---mounttypessh%5D(https://github.com/moby/buildkit/blob/master/frontend/dockerfile/docs/syntax.md#run---mounttypessh)) can be used to mount ssh key set by ID and access a secured resource: + +`RUN --mount=type=ssh,id=myproject git clone ...` + ### cache_from -`cache_from` defines a list of images that the Image builder SHOULD uses for cache resolution. +`cache_from` defines a list of sources the Image builder SHOULD use for cache resolution. + +Cache location syntax MUST follow the global format `[NAME|type=TYPE[,KEY=VALUE]]`. Simple `NAME` is actually a shortcut notation for `type=registry,ref=NAME`. + +Compose Builder implementations MAY support custom types, the Compose Specification defines canonical types which MUST be supported: + +- `registry` to retrieve build cache from an OCI image set by key `ref` + ```yml build: context: . cache_from: - alpine:latest - - corp/web_app:3.14 + - type=local,src=path/to/cache + - type=gha ``` +Unsupported caches MUST be ignored and not prevent user from building image. + +### cache_to + +`cache_to` defines a list of export locations to be used to share build cache with future builds. + +```yml +build: + context: . + cache_to: + - user/app:cache + - type=local,dest=path/to/cache +``` + +Cache target is defined using the same `type=TYPE[,KEY=VALUE]` syntax defined by [`cache_from`](#cache_from). + +Unsupported cache target MUST be ignored and not prevent user from building image. + ### extra_hosts `extra_hosts` adds hostname mappings at build-time. Use the same syntax as [extra_hosts](spec.md#extra_hosts). @@ -186,6 +250,16 @@ configuration, which means for Linux `/etc/hosts` will get extra lines: `isolation` specifies a build’s container isolation technology. Like [isolation](spec.md#isolation) supported values are platform-specific. +### privileged + +`privileged` configures the service image to build with elevated privileges. Support and actual impacts are platform-specific. + +```yml +build: + context: . + privileged: true +``` + ### labels `labels` add metadata to the resulting image. `labels` can be set either as an array or a map. @@ -210,6 +284,17 @@ build: - "com.example.label-with-empty-value" ``` +### no_cache + +`no_cache` disables image builder cache and enforce a full rebuild from source for all image layers. This only +applies to layers declared in the Dockerfile, referenced images COULD be retrieved from local image store whenever tag +has been updated on registry (see [pull](#pull)). + +### pull + +`pull` require the image builder to pull referenced images (`FROM` Dockerfile directive), even if those are already +available in the local image store. + ### shm_size `shm_size` set the size of the shared memory (`/dev/shm` partition on Linux) allocated for building Docker image. Specify @@ -237,6 +322,123 @@ build: target: prod ``` +### secrets +`secrets` grants access to sensitive data defined by [secrets](spec.md#secrets) on a per-service build basis. Two +different syntax variants are supported: the short syntax and the long syntax. + +Compose implementations MUST report an error if the secret isn't defined in the +[`secrets`](spec.md#secrets-top-level-element) section of this Compose file. + +#### Short syntax + +The short syntax variant only specifies the secret name. This grants the +container access to the secret and mounts it as read-only to `/run/secrets/` +within the container. The source name and destination mountpoint are both set +to the secret name. + +The following example uses the short syntax to grant the build of the `frontend` service +access to the `server-certificate` secret. The value of `server-certificate` is set +to the contents of the file `./server.cert`. + +```yml +services: + frontend: + build: + context: . + secrets: + - server-certificate +secrets: + server-certificate: + file: ./server.cert +``` + +#### Long syntax + +The long syntax provides more granularity in how the secret is created within +the service's containers. + +- `source`: The name of the secret as it exists on the platform. +- `target`: The name of the file to be mounted in `/run/secrets/` in the + service's task containers. Defaults to `source` if not specified. +- `uid` and `gid`: The numeric UID or GID that owns the file within + `/run/secrets/` in the service's task containers. Default value is USER running container. +- `mode`: The [permissions](http://permissions-calculator.org/) for the file to be mounted in `/run/secrets/` + in the service's task containers, in octal notation. + Default value is world-readable permissions (mode `0444`). + The writable bit MUST be ignored if set. The executable bit MAY be set. + +The following example sets the name of the `server-certificate` secret file to `server.crt` +within the container, sets the mode to `0440` (group-readable) and sets the user and group +to `103`. The value of `server-certificate` secret is provided by the platform through a lookup and +the secret lifecycle not directly managed by the Compose implementation. + +```yml +services: + frontend: + build: + context: . + secrets: + - source: server-certificate + target: server.cert + uid: "103" + gid: "103" + mode: 0440 +secrets: + server-certificate: + external: true +``` + +Service builds MAY be granted access to multiple secrets. Long and short syntax for secrets MAY be used in the +same Compose file. Defining a secret in the top-level `secrets` MUST NOT imply granting any service build access to it. +Such grant must be explicit within service specification as [secrets](spec.md#secrets) service element. + +### tags + +`tags` defines a list of tag mappings that MUST be associated to the build image. This list comes in addition of +the `image` [property defined in the service section](spec.md#image) + +```yml +tags: + - "myimage:mytag" + - "registry/username/myrepos:my-other-tag" +``` + +### platforms + +`platforms` defines a list of target [platforms](spec.md#platform). + +```yml +build: + context: "." + platforms: + - "linux/amd64" + - "linux/arm64" +``` + +When the `platforms` attribute is omitted, Compose implementations MUST include the service's platform +in the list of the default build target platforms. + +Compose implementations SHOULD report an error in the following cases: +* when the list contains multiple platforms but the implementation is incapable of storing multi-platform images +* when the list contains an unsupported platform +```yml +build: + context: "." + platforms: + - "linux/amd64" + - "unsupported/unsupported" +``` +* when the list is non-empty and does not contain the service's platform +```yml +services: + frontend: + platform: "linux/amd64" + build: + context: "." + platforms: + - "linux/arm64" +``` + ## Implementations * [docker-compose](https://docs.docker.com/compose) diff --git a/deploy.md b/deploy.md index cecf16a9..25b98629 100644 --- a/deploy.md +++ b/deploy.md @@ -1,7 +1,11 @@ # The Compose Specification - Deployment support +{:.no_toc} *Note:* Deployment is an OPTIONAL part of the Compose Specification +* ToC +{:toc} + ## Introduction Compose specification is a platform-neutral way to define multi-container applications. A Compose implementation supporting @@ -43,7 +47,7 @@ services: ### labels `labels` specifies metadata for the service. These labels MUST *only* be set on the service and *not* on any containers for the service. -This assumes the platform as some native concept of "service" that can match Compose application model. +This assumes the platform has some native concept of "service" that can match Compose application model. ```yml services: @@ -77,16 +81,16 @@ by a list or a map with string values. ```yml deploy: - placement: + placement: constraints: - - disktype=ssd + - disktype=ssd ``` ```yml deploy: - placement: + placement: constraints: - disktype: ssd + disktype: ssd ``` #### preferences @@ -96,16 +100,16 @@ by a list or a map with string values. ```yml deploy: - placement: + placement: preferences: - - datacenter=us-east + - datacenter=us-east ``` ```yml deploy: - placement: + placement: preferences: - datacenter: us-east + datacenter: us-east ``` ### replicas @@ -139,6 +143,7 @@ services: limits: cpus: '0.50' memory: 50M + pids: 1 reservations: cpus: '0.25' memory: 20M @@ -152,6 +157,10 @@ services: `memory` configures a limit or reservation on the amount of memory a container can allocate, set as a string expressing a [byte value](spec.md#specifying-byte-values). +#### pids + +`pids` tunes a container’s PIDs limit, set as an integer. + #### devices `devices` configures reservations of the devices a container can use. It contains a list of reservations, each set as an object with the following parameters: `capabilities`, `driver`, `count`, `device_ids` and `options`. @@ -249,11 +258,11 @@ deploy: ```yml deploy: - restart_policy: - condition: on-failure - delay: 5s - max_attempts: 3 - window: 120s + restart_policy: + condition: on-failure + delay: 5s + max_attempts: 3 + window: 120s ``` ### rollback_config @@ -282,8 +291,8 @@ deploy: ```yml deploy: - update_config: - parallelism: 2 - delay: 10s - order: stop-first + update_config: + parallelism: 2 + delay: 10s + order: stop-first ``` diff --git a/schema/compose-spec.json b/schema/compose-spec.json index 7d4285d5..6f827971 100644 --- a/schema/compose-spec.json +++ b/schema/compose-spec.json @@ -8,7 +8,12 @@ "properties": { "version": { "type": "string", - "description": "Version of the Compose specification used. Tools not implementing required version MUST reject the configuration file." + "description": "declared for backward compatibility, ignored." + }, + + "name": { + "type": "string", + "description": "define the Compose project name, until user defines one explicitly." }, "services": { @@ -86,13 +91,21 @@ "context": {"type": "string"}, "dockerfile": {"type": "string"}, "args": {"$ref": "#/definitions/list_or_dict"}, + "ssh": {"$ref": "#/definitions/list_or_dict"}, "labels": {"$ref": "#/definitions/list_or_dict"}, "cache_from": {"type": "array", "items": {"type": "string"}}, + "cache_to": {"type": "array", "items": {"type": "string"}}, + "no_cache": {"type": "boolean"}, "network": {"type": "string"}, + "pull": {"type": "boolean"}, "target": {"type": "string"}, "shm_size": {"type": ["integer", "string"]}, "extra_hosts": {"$ref": "#/definitions/list_or_dict"}, - "isolation": {"type": "string"} + "isolation": {"type": "string"}, + "privileged": {"type": "boolean"}, + "secrets": {"$ref": "#/definitions/service_config_or_secret"}, + "tags": {"type": "array", "items": {"type": "string"}}, + "platforms": {"type": "array", "items": {"type": "string"}} }, "additionalProperties": false, "patternProperties": {"^x-": {}} @@ -128,6 +141,7 @@ }, "cap_add": {"type": "array", "items": {"type": "string"}, "uniqueItems": true}, "cap_drop": {"type": "array", "items": {"type": "string"}, "uniqueItems": true}, + "cgroup": {"type": "string", "enum": ["host", "private"]}, "cgroup_parent": {"type": "string"}, "command": { "oneOf": [ @@ -135,26 +149,7 @@ {"type": "array", "items": {"type": "string"}} ] }, - "configs": { - "type": "array", - "items": { - "oneOf": [ - {"type": "string"}, - { - "type": "object", - "properties": { - "source": {"type": "string"}, - "target": {"type": "string"}, - "uid": {"type": "string"}, - "gid": {"type": "string"}, - "mode": {"type": "number"} - }, - "additionalProperties": false, - "patternProperties": {"^x-": {}} - } - ] - } - }, + "configs": {"$ref": "#/definitions/service_config_or_secret"}, "container_name": {"type": "string"}, "cpu_count": {"type": "integer", "minimum": 0}, "cpu_percent": {"type": "integer", "minimum": 0, "maximum": 100}, @@ -316,8 +311,9 @@ "type": "object", "properties": { "mode": {"type": "string"}, + "host_ip": {"type": "string"}, "target": {"type": "integer"}, - "published": {"type": "integer"}, + "published": {"type": ["string", "integer"]}, "protocol": {"type": "string"} }, "additionalProperties": false, @@ -330,7 +326,7 @@ "privileged": {"type": "boolean"}, "profiles": {"$ref": "#/definitions/list_of_strings"}, "pull_policy": {"type": "string", "enum": [ - "always", "never", "if_not_present", "build" + "always", "never", "if_not_present", "build", "missing" ]}, "read_only": {"type": "boolean"}, "restart": {"type": "string"}, @@ -342,30 +338,12 @@ }, "security_opt": {"type": "array", "items": {"type": "string"}, "uniqueItems": true}, "shm_size": {"type": ["number", "string"]}, - "secrets": { - "type": "array", - "items": { - "oneOf": [ - {"type": "string"}, - { - "type": "object", - "properties": { - "source": {"type": "string"}, - "target": {"type": "string"}, - "uid": {"type": "string"}, - "gid": {"type": "string"}, - "mode": {"type": "number"} - }, - "additionalProperties": false, - "patternProperties": {"^x-": {}} - } - ] - } - }, + "secrets": {"$ref": "#/definitions/service_config_or_secret"}, "sysctls": {"$ref": "#/definitions/list_or_dict"}, "stdin_open": {"type": "boolean"}, "stop_grace_period": {"type": "string", "format": "duration"}, "stop_signal": {"type": "string"}, + "storage_opt": {"type": "object"}, "tmpfs": {"$ref": "#/definitions/string_or_list"}, "tty": {"type": "boolean"}, "ulimits": { @@ -389,6 +367,7 @@ } }, "user": {"type": "string"}, + "uts": {"type": "string"}, "userns_mode": {"type": "string"}, "volumes": { "type": "array", @@ -407,7 +386,9 @@ "bind": { "type": "object", "properties": { - "propagation": {"type": "string"} + "propagation": {"type": "string"}, + "create_host_path": {"type": "boolean"}, + "selinux": {"type": "string", "enum": ["z", "Z"]} }, "additionalProperties": false, "patternProperties": {"^x-": {}} @@ -424,9 +405,12 @@ "type": "object", "properties": { "size": { - "type": "integer", - "minimum": 0 - } + "oneOf": [ + {"type": "integer", "minimum": 0}, + {"type": "string"} + ] + }, + "mode": {"type": "number"} }, "additionalProperties": false, "patternProperties": {"^x-": {}} @@ -514,7 +498,8 @@ "type": "object", "properties": { "cpus": {"type": ["number", "string"]}, - "memory": {"type": "string"} + "memory": {"type": "string"}, + "pids": {"type": "integer"} }, "additionalProperties": false, "patternProperties": {"^x-": {}} @@ -705,6 +690,7 @@ "type": "object", "properties": { "name": {"type": "string"}, + "environment": {"type": "string"}, "file": {"type": "string"}, "external": { "type": ["boolean", "object"], @@ -767,7 +753,7 @@ "type": "object", "patternProperties": { ".+": { - "type": ["string", "number", "null"] + "type": ["string", "number", "boolean", "null"] } }, "additionalProperties": false @@ -793,6 +779,27 @@ "additionalProperties": false }, + "service_config_or_secret": { + "type": "array", + "items": { + "oneOf": [ + {"type": "string"}, + { + "type": "object", + "properties": { + "source": {"type": "string"}, + "target": {"type": "string"}, + "uid": {"type": "string"}, + "gid": {"type": "string"}, + "mode": {"type": "number"} + }, + "additionalProperties": false, + "patternProperties": {"^x-": {}} + } + ] + } + }, + "constraints": { "service": { "id": "#/definitions/constraints/service", diff --git a/spec.md b/spec.md index 3a8a1eee..776c987a 100644 --- a/spec.md +++ b/spec.md @@ -1,19 +1,8 @@ # The Compose Specification +{:.no_toc} -## Table of Contents - -- [Status of this document](#status-of-this-document) -- [The Compose application model](#the-compose-application-model) -- [Compose file](#compose-file) -- [Version top-level element](#version-top-level-element) -- [Services top-level element](#services-top-level-element) -- [Networks top-level element](#networks-top-level-element) -- [Volumes top-level element](#volumes-top-level-element) -- [Configs top-level element](#configs-top-level-element) -- [Secrets top-level element](#secrets-top-level-element) -- [Fragments](#fragments) -- [Extension](#extension) -- [Interpolation](#interpolation) +* ToC +{:toc} ## Status of this document @@ -31,7 +20,7 @@ is Platform dependent and can only be confirmed at runtime. The definition of a 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. +The specification defines the expected configuration syntax and behavior, 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: @@ -44,15 +33,15 @@ to support those running modes: 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. +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 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. +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. +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. +A [Secret](#secrets-top-level-element) is a specific flavor 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. @@ -60,6 +49,8 @@ A **Project** is an individual deployment of an application specification on a p 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`. +Project name can be set explicitly by top-level `name` attribute. Compose implementation MUST offer a way for user to set a custom project name and override this name, so that the same `compose.yaml` file can be deployed twice on the same infrastructure, without changes, by just passing a distinct name. + ### Illustrative example The following example illustrates Compose specification concepts with a concrete example application. The example is non-normative. @@ -230,9 +221,27 @@ Top-level `version` property is defined by the specification for backward compat 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 +Compose implementations SHOULD validate whether 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). +SHOULD warn the user. Compose implementations MAY offer options to ignore unknown fields (as defined by ["loose"](#requirements-and-optional-attributes) mode). + +## Name top-level element + +Top-level `name` property is defined by the specification as project name to be used if user doesn't set one explicitly. +Compose implementations MUST offer a way for user to override this name, and SHOULD define a mechanism to compute a +default project name, to be used if the top-level `name` element is not set. + +Whenever project name is defined by top-level `name` or by some custom mechanism, it MUST be exposed for +[interpolation](#interpolation) and environment variable resolution as `COMPOSE_PROJECT_NAME` + +```yml +services: + foo: + image: busybox + environment: + - COMPOSE_PROJECT_NAME + command: echo "I'm running ${COMPOSE_PROJECT_NAME}" +``` ## Services top-level element @@ -250,18 +259,21 @@ Each service MAY also include a Build section, which defines how to create the D 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) +Build support is an OPTIONAL aspect of the Compose specification, and is +described in detail in the [Build support](build.md) documentation. 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 support is an OPTIONAL aspect of the Compose specification, and is +described in detail in the [Deployment support](deploy.md) documentation. +If not implemented the Deploy section SHOULD be ignored and the Compose file MUST still be considered valid. -### deploy +### build + +`build` specifies the build configuration for creating container image from source, as defined in the [Build support](build.md) documentation. -`deploy` specifies the configuration for the deployment and lifecycle of services, as defined [here](deploy.md). ### blkio_config @@ -371,9 +383,6 @@ _DEPRECATED: use [deploy.reservations.cpus](deploy.md#cpus)_ `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 @@ -396,6 +405,14 @@ cap_drop: - SYS_ADMIN ``` +### cgroup + +`cgroup` specifies the cgroup namespace to join. When unset, it is container runtime decision to +select cgroup namespace to use, if supported. + +- `host`: Run the container in the Container runtime cgroup namespace +- `private`: Run the container in its own private cgroup namespace + ### cgroup_parent `cgroup_parent` specifies an OPTIONAL parent [cgroup](http://man7.org/linux/man-pages/man7/cgroups.7.html) for the container. @@ -406,7 +423,7 @@ cgroup_parent: m-executor-abcd ### command -`command` overrides the the default command declared by the container image (i.e. by Dockerfile's `CMD`). +`command` overrides the default command declared by the container image (i.e. by Dockerfile's `CMD`). ``` command: bundle exec thin -p 3000 @@ -449,6 +466,7 @@ services: image: redis:latest configs: - my_config + - my_other_config configs: my_config: file: ./my_config.txt @@ -633,6 +651,12 @@ starting a dependent service. Compose implementations MUST guarantee dependency services marked with `service_healthy` are "healthy" before starting a dependent service. + +### deploy + +`deploy` specifies the configuration for the deployment and lifecycle of services, as defined [here](deploy.md). + + ### device_cgroup_rules `device_cgroup_rules` defines a list of device cgroup rules for this container. @@ -647,11 +671,13 @@ device_cgroup_rules: ### devices -`devices` defines a list of device mappings for created containers. +`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 @@ -765,7 +791,7 @@ 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, MUST be enclosed in quotes to ensure +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 @@ -1014,7 +1040,9 @@ external_links: ### 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`. + +#### Short syntax +Short syntax use plain strings in a list. Values MUST set hostname and IP address for additional hosts in the form of `HOSTNAME:IP`. ```yml extra_hosts: @@ -1022,6 +1050,15 @@ extra_hosts: - "otherhost:50.31.209.229" ``` +#### Long syntax +Alternatively, `extra_hosts` can be set as a mapping between hostname(s) and IP(s) + +```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: @@ -1108,7 +1145,7 @@ as `[/][/][:|@]`. ```yml image: redis image: redis:5 - image: redis@sha356:0ed5d5928d4737458944eb604cc8509e245c3e19d02ad83935398bc4b991aac7 + image: redis@sha256:0ed5d5928d4737458944eb604cc8509e245c3e19d02ad83935398bc4b991aac7 image: library/redis image: docker.io/library/redis image: my_private.registry:5000/redis @@ -1151,6 +1188,17 @@ which MUST be implemented as described if supported: ipc: "service:[service name]" ``` +### uts + +`uts` configures the UTS namespace mode set for the service container. When unspecified +it is the runtime's decision to assign a UTS namespace, if supported. Available values are: + +- `'host'` which results in the container using the same UTS namespace as the host. + +```yml + uts: "host" +``` + ### isolation `isolation` specifies a container’s isolation technology. Supported values are platform-specific. @@ -1432,9 +1480,11 @@ be within [-1000,1000] range. `pid` sets the PID mode for container created by the Compose implementation. Supported values are platform specific. -### pid_limit +### pids_limit -`pid_limit` tunes a container’s PIDs limit. Set to -1 for unlimited PIDs. +_DEPRECATED: use [deploy.reservations.pids](deploy.md#pids)_ + +`pids_limit` tunes a container’s PIDs limit. Set to -1 for unlimited PIDs. ```yml pids_limit: 10 @@ -1443,11 +1493,13 @@ pids_limit: 10 ### platform `platform` defines the target platform containers for this service will run on, using the `os[/arch[/variant]]` syntax. +The values of `os`, `arch`, and `variant` MUST conform to the convention used by the [OCI Image Spec](https://github.com/opencontainers/image-spec/blob/v1.0.2/image-index.md). + 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: darwin platform: windows/amd64 platform: linux/arm64/v8 ``` @@ -1459,7 +1511,7 @@ Port mapping MUST NOT be used with `network_mode: host` and doing so MUST result #### Short syntax -The short syntax is a comma-separated string to set host IP, host port and container port +The short syntax is a colon-separated string to set host IP, host port and container port in the form: `[HOST:]CONTAINER[/PROTOCOL]` where: @@ -1487,6 +1539,7 @@ ports: - "8000:8000" - "9090-9091:8080-8081" - "49100:22" + - "8000-9000:80" - "127.0.0.1:8001:8001" - "127.0.0.1:5000-5010:5000-5010" - "6060:6060/udp" @@ -1501,14 +1554,22 @@ The long form syntax allows the configuration of additional fields that can't be expressed in the short form. - `target`: the container port -- `published`: the publicly exposed port +- `published`: the publicly exposed port. Can be set as a range using syntax `start-end`, so it is defined as a string, then actual port SHOULD be assigned within this range based on available ports. +- `host_ip`: the Host IP mapping, unspecified means all network interfaces (`0.0.0.0`) - `protocol`: the port protocol (`tcp` or `udp`), unspecified means any protocol - `mode`: `host` for publishing a host port on each node, or `ingress` for a port to be load balanced. ```yml ports: - target: 80 - published: 8080 + host_ip: 127.0.0.1 + published: "8080" + protocol: tcp + mode: host + + - target: 80 + host_ip: 127.0.0.1 + published: "8000-9000" protocol: tcp mode: host ``` @@ -1574,13 +1635,13 @@ web: ### scale --DEPRECATED: use [deploy/replicas](deploy.md#replicas)_ +_DEPRECATED: use [deploy/replicas](deploy.md#replicas)_ `scale` specifies the default number of containers to deploy for this service. ### secrets -`secrets` grants access to sensitive data defined by [secrets](secrets) on a per-service basis. Two +`secrets` grants access to sensitive data defined by [secrets](#secrets) on a per-service basis. Two different syntax variants are supported: the short syntax and the long syntax. Compose implementations MUST report an error if the secret doesn't exist on the platform or isn't defined in the @@ -1615,7 +1676,7 @@ the service's containers. - `source`: The name of the secret as it exists on the platform. - `target`: The name of the file to be mounted in `/run/secrets/` in the - service's task containers. Defaults to `source` if not specified. + service's task container, or absolute path of the file if an alternate location is required. Defaults to `source` if not specified. - `uid` and `gid`: The numeric UID or GID that owns the file within `/run/secrets/` in the service's task containers. Default value is USER running container. - `mode`: The [permissions](http://permissions-calculator.org/) for the file to be mounted in `/run/secrets/` @@ -1626,7 +1687,7 @@ the service's containers. The following example sets the name of the `server-certificate` secret file to `server.crt` within the container, sets the mode to `0440` (group-readable) and sets the user and group to `103`. The value of `server-certificate` secret is provided by the platform through a lookup and -the secret lifecycle not directly managed by the Compose implementation. +the secret lifecycle is not directly managed by the Compose implementation. ```yml services: @@ -1644,7 +1705,7 @@ secrets: ``` Services MAY be granted access to multiple secrets. Long and short syntax for secrets MAY be used in the -same Compose file. Defining a secret in the top-level `secrets` MUTS NOT imply granting any service access to it. +same Compose file. Defining a secret in the top-level `secrets` MUST NOT imply granting any service access to it. Such grant must be explicit within service specification as [secrets](#secrets) service element. ### security_opt @@ -1689,6 +1750,15 @@ If unset containers are stopped by the Compose Implementation by sending `SIGTER stop_signal: SIGUSR1 ``` +### storage_opt + +`storage_opt` defines storage driver options for a service. + +```yml +storage_opt: + size: '1G' +``` + ### sysctls `sysctls` defines kernel parameters to set in the container. `sysctls` can use either an array or a map. @@ -1788,11 +1858,18 @@ volumes: #### Short syntax -The short syntax uses a single string with comma-separated values to specify a volume mount -(`VOLUME:CONTAINER_PATH`), or an access mode (`VOLUME:CONTAINER:ACCESS_MODE`). +The short syntax uses a single string with colon-separated values to specify a volume mount +(`VOLUME:CONTAINER_PATH`), or an access mode (`VOLUME:CONTAINER_PATH:ACCESS_MODE`). + +- `VOLUME`: MAY be either a host path on the platform hosting containers (bind mount) or a volume name +- `CONTAINER_PATH`: the path in the container where the volume is mounted +- `ACCESS_MODE`: is a comma-separated `,` list of options and MAY be set to: + - `rw`: read and write access (default) + - `ro`: read-only access + - `z`: SELinux option indicates that the bind mount host content is shared among multiple containers + - `Z`: SELinux option indicates that the bind mount host content is private and unshared for other containers -`VOLUME` MAY be either a host path on the platform hosting containers (bind mount) or a volume name. -`ACCESS_MODE` MAY be set as read-only by using `ro` or read and write by using `rw` (default). +> **Note**: The SELinux re-labeling bind mount option is ignored on platforms without SELinux. > **Note**: Relative host paths MUST only be supported by Compose implementations that deploy to a > local container runtime. This is because the relative path is resolved from the Compose file’s parent @@ -1813,10 +1890,15 @@ expressed in the short form. - `read_only`: flag to set the volume as read-only - `bind`: configure additional bind options - `propagation`: the propagation mode used for the bind + - `create_host_path`: create a directory at the source path on host if there is nothing present. + Do nothing if there is something present at the path. This is automatically implied by short syntax + for backward compatibility with docker-compose legacy. + - `selinux`: the SELinux re-labeling option `z` (shared) or `Z` (private) - `volume`: configure additional volume options - `nocopy`: flag to disable copying of data from a container when a volume is created - `tmpfs`: configure additional tmpfs options - - `size`: the size for the tmpfs mount in bytes + - `size`: the size for the tmpfs mount in bytes (either numeric or as bytes unit) + - `mode`: the filemode for the tmpfs mount as Unix permission bits as an octal number - `consistency`: the consistency requirements of the mount. Available values are platform specific ### volumes_from @@ -2002,6 +2084,9 @@ Compose implementations MUST set `com.docker.compose.project` and `com.docker.co If set to `true`, `external` specifies that this network’s lifecycle is maintained outside of that of the application. Compose Implementations SHOULD NOT attempt to create these networks, and raises an error if one doesn't exist. +If `external` is set to `true` and network configuration has other but `name` attributes set, considering resource is +not managed by compose lifecycle, Compose Implementations SHOULD reject a Compose file as invalid. + In the example below, `proxy` is the gateway to the outside world. Instead of attempting to create a network, Compose implementations SHOULD interrogate the platform for an existing network simply called `outside` and connect the `proxy` service's containers to it. @@ -2051,8 +2136,8 @@ Volumes are persistent data stores implemented by the platform. The Compose spec for services to mount volumes, and configuration parameters to allocate them on infrastructure. The `volumes` section allows the configuration of named volumes that can be reused across multiple services. Here's -an example of a two-service setup where a database's data directory is shared with another service as a volume so -that it can be periodically backed up: +an example of a two-service setup where a database's data directory is shared with another service as a volume named +`db-data` so that it can be periodically backed up: ```yml services: @@ -2100,9 +2185,13 @@ If set to `true`, `external` specifies that this volume already exist on the pla of that of the application. Compose implementations MUST NOT attempt to create these volumes, and MUST return an error if they do not exist. +If `external` is set to `true` and volume configuration has other but `name` attributes set, considering resource is +not managed by compose lifecycle, Compose Implementations SHOULD reject a Compose file as invalid. + + In the example below, instead of attempting to create a volume called -`{project_name}_data`, Compose looks for an existing volume simply -called `data` and mount it into the `db` service's containers. +`{project_name}_db-data`, Compose looks for an existing volume simply +called `db-data` and mounts it into the `backend` service's containers. ```yml services: @@ -2204,7 +2293,7 @@ configs: file: ./httpd.conf ``` -Alternatively, `http_config` can be declared as external, doing so Compose implementation will lookup `server-certificate` to expose configuration data to relevant services. +Alternatively, `http_config` can be declared as external, doing so Compose implementation will lookup `http_config` to expose configuration data to relevant services. ```yml configs: @@ -2224,6 +2313,9 @@ configs: name: "${HTTP_CONFIG_KEY}" ``` +If `external` is set to `true` and secret configuration has other but `name` attributes set, considering resource is +not managed by compose lifecycle, Compose Implementations SHOULD reject a Compose file as invalid. + Compose file need to explicitly grant access to the configs to relevant services in the application. ## Secrets top-level element @@ -2234,13 +2326,14 @@ The top-level `secrets` declaration defines or references sensitive data that ca application. The source of the secret is either `file` or `external`. - `file`: The secret is created with the contents of the file at the specified path. +- `environment`: The secret is created with the value of an environment variable. - `external`: If set to true, specifies that this secret has already been created. Compose implementation does not attempt to create it, and if it does not exist, an error occurs. - `name`: The name of the secret object in Docker. This field can be used to reference secrets that contain special characters. The name is used as is and will **not** be scoped with the project name. -In this example, `server-certificate` is created as `_server-certificate` when the application is deployed, +In this example, `server-certificate` secret is created as `_server-certificate` when the application is deployed, by registering content of the `server.cert` as a platform secret. ```yml @@ -2249,6 +2342,15 @@ secrets: file: ./server.cert ``` +In this example, `token` secret is created as `_token` when the application is deployed, +by registering content of the `OAUTH_TOKEN` environment variable as a platform secret. + +```yml +secrets: + token: + environment: "OAUTH_TOKEN" +``` + Alternatively, `server-certificate` can be declared as external, doing so Compose implementation will lookup `server-certificate` to expose secret to relevant services. ```yml @@ -2269,6 +2371,9 @@ secrets: name: "${CERTIFICATE_KEY}" ``` +If `external` is set to `true` and secret configuration has other but `name` attributes set, considering resource is +not managed by compose lifecycle, Compose Implementations SHOULD reject a Compose file as invalid. + Compose file need to explicitly grant access to the secrets to relevant services in the application. ## Fragments @@ -2413,6 +2518,12 @@ Similarly, the following syntax allows you to specify mandatory variables: - `${VARIABLE?err}` exits with an error message containing `err` if `VARIABLE` is unset in the environment. +Interpolation can also be nested: + +- `${VARIABLE:-${FOO}}` +- `${VARIABLE?$FOO}` +- `${VARIABLE:-${FOO:-default}}` + Other extended shell-style features, such as `${VARIABLE/foo/bar}`, are not supported by the Compose specification.