Services top-level element
A service is an abstract definition of a computing resource within an application which can be scaled or replaced independently from other components. Services are backed by a set of containers, run by the platform according to replication requirements and placement constraints. As services are backed by containers, they 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 top-level 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
service container.
Each service may also include a build section, which defines how to create the Docker image for the service.
Compose supports building docker images using this service definition. If not used, the build section is ignored and the Compose file is still considered valid. Build support is an optional aspect of the Compose Specification, and is
described in detail in the Compose Build Specification 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 Compose Deploy Specification documentation.
If not implemented the deploy section is ignored and the Compose file is still considered valid.
A service definition supports all attributes defined in the Container Specification and the Workload Specification, as well as the following service-specific attributes.
attach
When attach is defined and set to false Compose does not collect service logs,
until you explicitly request it to.
The default service configuration is attach: true.
container_name
container_name is a string that specifies a custom container name, rather than a name generated by default.
container_name: my-web-container
Compose does not scale a service beyond one container if the Compose file specifies a
container_name. Attempting to do so results in an error.
container_name follows the regex format of [a-zA-Z0-9][a-zA-Z0-9_.-]+
deploy
deploy specifies the configuration for the deployment and lifecycle of services, as defined in the Compose Deploy Specification.
develop
develop specifies the development configuration for maintaining a container in sync with source, as defined in the Development Section.
extends
extends lets you share common configurations among different files, or even different projects entirely. With extends you can define a common set of service options in one place and refer to it from anywhere. You can refer to another Compose file and select a service you want to also use in your own application, with the ability to override some attributes for your own needs.
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.
extends:
file: common.yml
service: webapp
service: Defines the name of the service being referenced as a base, for examplewebordatabase.file: The location of a Compose configuration file defining that service.
Restrictions
When a service is referenced using extends, it can declare dependencies on other resources. These dependencies
may be explicitly defined through attributes like volumes, networks, configs, secrets, links, volumes_from,
or depends_on. Alternatively, dependencies can reference another service using the service:{name} syntax in
namespace declarations such as ipc, pid, or network_mode.
Compose does not automatically import these referenced resources into the extended model. It is the responsibility
of the Compose file author to ensure all required resources are explicitly declared in the model that relies on extends.
Circular references with extends are not supported, Compose returns an error when one is detected.
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.
A service denoted by service must be present in the identified referenced Compose file.
Compose returns an error if:
- The service denoted by
serviceis not found. - The Compose file denoted by
fileis not found.
Merging service definitions
Two service definitions, the main one in the current Compose file and the referenced one
specified by extends, are merged in the following way:
- Mappings: Keys in mappings of the main service definition override keys in mappings of the referenced service definition. Keys that aren’t overridden are included as is.
- Sequences: Items are combined together into a new sequence. The order of elements is preserved with the referenced items coming first and main items after.
- Scalars: Keys in the main service definition take precedence over keys in the referenced one.
Mappings
The following keys should be treated as mappings: annotations, 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 the main mapping cannot specify
disable: true unless the referenced mapping also specifies disable: true. Compose returns an error in this case.
For example, the input below:
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.
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:
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 the mounted path
now points to the new volume name and ro flag was applied.
image: busybox
volumes:
- cli-volume:/var/lib/backup/data:ro
If the referenced service definition contains extends mapping, the items under it
are simply copied into the new merged definition. The merging process is then kicked
off again until no extends keys are remaining.
For example, the input below:
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.
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:
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.
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 of your 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.
external_links:
- redis
- database:mysql
- database:postgresql
links
Note
Availability of the
linksattribute is implementation specific.
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.
web:
links:
- db
- db:database
- redis
Containers for the linked service are reachable at a hostname identical to the alias, or the service name if no alias is specified.
Links are not required to enable services to communicate. When no specific network configuration is set,
any service is 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 does not override the network configuration and services not
attached to a shared network are not be able to communicate. Compose doesn’t warn you about a configuration mismatch.
Links also express implicit dependency between services in the same way as depends_on, so they determine the order of service startup.
post_start
post_start defines a sequence of lifecycle hooks to run after a container has started. The exact timing of when the command is run is not guaranteed.
command: The command to run after the container has started. This attribute is required.user: The user to run the command. If not set, the command is run with the same user as the main service command.privileged: Lets the post_start command run with privileged access.working_dir: The working directory in which to run the command. If not set, it is run in the same working directory as the main service command.environment: Sets the environment variables to run the post_start command. The command inherits theenvironmentset for the service’s main command, and this section lets you to append or override values.
services:
test:
post_start:
- command: ./do_something_on_startup.sh
user: root
privileged: true
environment:
- FOO=BAR
pre_start
pre_start defines a sequence of init containers to run before the service container is started. Each step runs to completion, in declared order, and the service container only starts once every step has exited 0. A non-zero exit fails the bring-up of the service and its dependents.
Unlike post_start and pre_stop, which run a command inside the running service container, each pre_start step runs in its own ephemeral container, created after the service container is created but before it is started.
A pre_start step is a full container specification: any container
attribute can be declared on the step. Undeclared attributes are inherited from the service:
a pre_start container is the service container with the image, the command — and whatever
else the step declares — replaced. In particular:
image: if omitted, the parent service’s image is used.command: optional when the chosen image’s entrypoint already runs the intended command.environment: the step inherits the environment of the service’s main command; declared values are appended to or override the inherited ones.volumes: if omitted, the step shares the service’s declared volume mounts; re-declaring a mount overrides how the step mounts it (for example read-write where the service mounts read-only).
Re-declaring an inherited attribute follows the same merge rules as Compose
override files: mappings merge, scalars replace, sequences append, and the
!reset and !override tags are available.
Attributes that only make sense for an orchestrated workload are not part of the container
specification and cannot be declared on a step (ports, healthcheck, depends_on,
build, …) — see the Workload specification.
In addition to container attributes, a step supports:
per_replica: Whether the step runs once per service replica (true), or once for the service as a whole before any replica starts (false, the default). Set totruefor per-instance work such as initializing a replica’s anonymous volumes or registering per-replica network identity.
pre_start steps only run once the service’s depends_on conditions have been satisfied, so a step can rely on those dependencies the same way the main service command does. A pre_start container joins the same networks as the service, so it can reach services declared in depends_on, and shares the service’s declared volume mounts so files it produces in a shared volume are visible to the service.
With per_replica: false and a scaled service, only mounts that are shared across replicas (named volumes, bind mounts) are usable; per-instance mounts (tmpfs, anonymous volumes) cannot be addressed by a single run. This is not an error: the steps run without access to per-instance mounts. Data a per_replica: false step must share with the service belongs in a named volume or bind mount.
With per_replica: true, a step runs once per replica, and each run is tied to its replica: it shares that replica’s volume mounts and must complete successfully before that replica’s container starts. The declared order of steps is preserved for each replica, but runs for distinct replicas may execute concurrently. A non-zero exit prevents the associated replica from starting and fails the bring-up of the service as described above.
A pre_start step that has already succeeded for its current definition is not re-run on a subsequent up, nor when the service container restarts under its restart policy. A step runs again when its definition — any of its attributes — changes, when the previous run did not succeed, or when the service container is recreated (for example, after a change to the service configuration or an explicit forced recreation).
services:
app:
image: myapp:latest
depends_on:
db:
condition: service_healthy
pre_start:
- command: ["./manage.py", "migrate"]
- image: busybox
command: sh -c 'chown -R 1000:1000 /data'
volumes:
- data:/data
db:
image: postgres:16
volumes:
data:
pre_stop
pre_stop defines a sequence of lifecycle hooks to run before service termination.
Configuration is equivalent to post_start.
profiles
profiles defines a list of named profiles for the service to be enabled under. If unassigned, the service is always started but if assigned, it is only started if the profile is activated.
If present, profiles follow the regex format of [a-zA-Z0-9][a-zA-Z0-9_.-]+.
services:
frontend:
image: frontend
profiles: ["frontend"]
phpmyadmin:
image: phpmyadmin
depends_on:
- db
profiles:
- debug
provider
provider can be used to define a service that Compose won’t manage directly. Compose will delegate the service lifecycle to a dedicated or third-party component.
database:
provider:
type: awesomecloud
options:
type: mysql
foo: bar
app:
image: myapp
depends_on:
- database
As Compose runs the application, the awesomecloud binary is used to manage the database service setup.
Dependent service app receives additional environment variables prefixed by service name, so it can access the resource.
For illustration, assuming awesomecloud execution produced variables URL and API_KEY, the app service will
run with environment variables DATABASE_URL and DATABASE_API_KEY.
As Compose stops the application, the awesomecloud binary is used to manage the database service teardown.
The mechanism used by Compose to delegate service lifecycle to an external binary is described here.
type
type attribute is required. It defines the external component used by Compose to manage setup and teardown lifecycle
events.
options
options are specific to the selected provider and not validated by the compose specification
restart
restart defines the policy that the platform applies on container termination.
no: The default restart policy. It does not restart the container under any circumstances.always: The policy always restarts the container until its removal.on-failure[:max-retries]: The policy restarts the container if the exit code indicates an error. Optionally, limit the number of restart retries the container runtime attempts.unless-stopped: The policy restarts the container irrespective of the exit code but stops restarting when the service is stopped or removed.
restart: "no"
restart: always
restart: on-failure
restart: on-failure:3
restart: unless-stopped
scale
scale specifies the default number of containers to deploy for this service.
When both are set, scale must be consistent with the replicas attribute in the Deploy Specification.