Skip to main content

How to create a Docker-Compose file

- Rule 1: services

A Compose file MUST declare a services key in the root.
The services value is an object (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 in the Build support 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 in the Deployment support documentation. If not implemented the Deploy section SHOULD be ignored and the Compose file MUST still be considered valid.


- Rule 2: services.image

image specifies the image to start the container from.
image MUST follow the Open Container Specification addressable image format, as [%registry%/][%project%/]%image%[:%tag%|@%digest%].

image: redis
image: redis:5
image: redis@sha256:0ed5d5928d4737458944eb604cc8509e245c3e19d02ad83935398bc4b991aac7
image: library/redis
image: docker.io/library/redis
image: my_private.registry:5000/redis

- Rule 3: services.build

  • build build an OPTIONAL build subsection on services build specifies the build configuration for creating container image from source. When a Build subsection is present for a service, it is valid for a Compose file to miss an Image attribute for corresponding service, as Compose implementation can build image from source.

  • build.context v.s. build = context Build can be either specified as a single string defining a context path, or as a detailed build definition. In the former case, the whole path is used as a Docker context to execute a docker build, looking for a canonical Dockerfile at context root. Context path can be absolute or relative, and if so relative path MUST be resolved from Compose file parent folder. As an absolute path prevent the Compose file to be portable, Compose implementation SHOULD warn user accordingly.

  • build.dockerfile In the later case, build arguments can be specified, including an alternate Dockerfile location. This one can be absolute or relative path. If Dockerfile path is relative, it MUST be resolved from context path. As an absolute path prevent the Compose file to be portable, Compose implementation SHOULD warn user if an absolute alternate Dockerfile path is used.

  • Consistency with Image When service definition do include both Image attribute and a Build section, Compose implementation can't guarantee a pulled image is strictly equivalent to building the same image from sources. Without any explicit user directives, Compose implementation with Build support MUST first try to pull Image, then build from source if image was not found on registry. Compose implementation MAY offer options to customize this behavior by user request.

  • Illustrative sample

    services:
    frontend:
    image: awesome/webapp
    build: ./webapp

    backend:
    image: awesome/database
    build:
    context: backend
    dockerfile: ../backend.Dockerfile

    custom:
    build: ~/custom

    When used to build service images from source, such a Compose file will create three docker images: • 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.

  • Build Definition The build element define configuration options that are applied by Compose implementations to build Docker image from source. build can be specified either as a string containing a path to the build context or a detailed structure: Using this string syntax, only the build context can be configured as either: • a relative path to the Compose file's parent folder. This path MUST be a directory and contain a Dockerfile

    services:
    webapp:
    build: ./dir

    • a git repository URL. Git URLs accept context configuration in their fragment section, separated by a colon (:). The first part represents the reference that Git will check out, and can be either a branch, a tag, or a remote reference. The second part represents a subdirectory inside the repository that will be used as a build context. services: webapp: build: https://github.com/mycompany/example.git#branch_or_tag:subdirectory


- Rule 4: services.build.context (REQUIRED)

context defines either a path to a directory containing a Dockerfile, or a url to a git repository. 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 from being portable.

This:
build:
context: ./dir
V.S. this:
services:
webapp:
build: https://github.com/mycompany/webapp.git

- Rule 5: services.build.dockerfile

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 from being portable. When set, dockerfile_inline attribute is not allowed and a Compose Implementation SHOULD reject any Compose file having both set.

build:
context: .
dockerfile: webapp.Dockerfile

- Rule 6: services.build.dockerfile_inline

dockerfile_inline allows to define Dockerfile content as inlined string in a Compose file. When set, dockerfile attribute is not allowed and a Compose Implementation SHOULD reject any Compose file having both set. Use of YAML multi-line string syntax is recommended to define Dockerfile content:

build:
context: .
dockerfile_inline: |
FROM baseimage
RUN some command

- Rule 7: services.build.args

args define build arguments, i.e. Dockerfile ARG values.
args can be set in Compose file under the build key to define some arguments.
args can be set a mapping or a list:

// Way number 1:
build:
context: .
args:
GIT_COMMIT: %some-value%
// Way number 2:
build:
context: .
args: - GIT_COMMIT=%some-value%

-- HARDCODED:

args can be hardcoded:

build:
context: .
args: - VERDION=0.0.1

-- PASSED FROM OUTSIDE:

args can be passed from outside:

build:
context: .
args:
# The names do not need to match! First VERSION is the inner name, second VERSION is the outer name.
- VERSION=${VERSION:-0.0.1}

In which, you would call the build sub-command like so:

VERSION=1.2.3 docker-compose build --no-cache

- Rule 8: services.build.privileged

privileged configures the service image to build with elevated privileges. Support and actual impacts are platform-specific. build: context: . privileged: true


- Rule 9: services.build.labels

labels add metadata to the resulting image. labels can be set either as an array or a map. This:

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

V.S. this:

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

- Rule 10: services.build.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).

services:
users-service:
image: users-service
build:
no_cache: true

- Rule 11: services.build.pull

pull require the image builder to pull referenced images (FROM Dockerfile directive), even if those are already available in the local image store.


- Rule 12: services.build.shm_size

shm_size set the size of the shared memory (/dev/shm partition on Linux) allocated for building Docker image. Specify as an integer value representing the number of bytes or as a string expressing a byte value.

Byte values:

  • 2b
  • 1024kb
  • 2048k
  • 300m
  • 1gb

This:

build:
context: .
shm_size: '2gb'

V.S. this:

build:
context: .
shm_size: 10000000

- Rule 13: services.build.secrets

Docker Secrets are only available in Swarm mode, so standalone containers can not use this feature. A given secret is only accessible to those services which have been granted explicit access to it, and while they're running.


- Rule 14: services.build.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 tags:

  • "myimage:mytag"
  • "registry/username/myrepos:my-other-tag"

- Rule 15: services.env_file

Defining an env_file inside the yaml will take environment variables from the file and inject them into the container. That makes it visible to your application, but cannot be used for variables inside your yaml that you want docker-compose to expand since that variable expansion happens before the env_file contents are parsed.

services:
users-service:
env_file: .env

When both env_file and environment are set for a service, values set by environment have precedence.