Docker Compose
It helps you configuring and starting multi-container applications.
Compose simplifies the control of the entire application stack, facilitating the management of services, networks and volumes in a single YAML configuration file (usually compose.yaml). And with simple Compose CLI commands you can bring UP or DOWN an entire container network.
docker-compose.yaml and docker-compose.yml are also reconized ONLY for backward compatibility.
Use compose.yaml.
compose.yaml doesn't replace the Dockerfile.
Not all of the configurations in Dockerfile can be done in the compose.yaml.
Compose How-tos
You may also use fragments and extensions to keep your Compose files easy to maintain.
These muliple Compose files can be merged together to define the application model.
docker compose -f angular-compose.yaml -f node-compose.yaml.
It merges files in the order they are specified on the command line. Subsequent files may merge, override, or add to their predecessors.
Meaning that if a
servicewith the same name is in two different merging files, their configurations might be overriden or added.For single-value options the value is replaced.
For multi-value options the values are added.
For
<key><value>options, the values might get added or overwritten.For
volumesanddevices, values are merged using the mount path in the container.
Some rules for merging files:
Make sure all paths in the files are relative to the base Compose file (the first file specified with
-fon the command line)Use
docker compose configto review your merged configuration.
Compose automatically searches on the same folder and parent folder for compose.yaml and compose.override.yaml and merges them by default.
You can also supply configurations from the STDIN with - after -f:
To easy modularize complex applications into sub-Compose files. Each path listed in the include section loads as an individual Compose application model, with it's own project directory, in order to resolve relative paths.
Override services
Compose reports an error if any resource from include conflicts with resources from the included Compose file.
So, to tweak configurations from the included file you add an override file to the include directive, for overwriting specific files.
Or, if you need to override multiple files and don't want to create multiple override files, you may create a single global compose.override.yaml file.
Useful for reusing service options, from other files or from the same file.
volumes_from and depends_on are never shared, to avoid implicit dependencies.
When Docker Compose runs a container, it uses ENTRYPOINT and CMD to manage what happens when the containers starts and stops.
In Compose you may handle these separatly with lifecycle hooks - (commands that run right after the container starts or just before it stops).
Lifecycle hooks also have special privileges (like running as the root user), even when the container itself runs with lower privileges for security.
Post-start hooks
Commands that runs right after a container starts.
Pre-stop hooks
Commands that runs before the container stops. (docker compose down or manually with Ctrl+C)
These hooks won't work if the container stops by itself or gets killed suddently.
profiles help you adjust your Compose application for different environments or use cases, by selectively activating services.
Starting profiles
Starting specific profiles (--profile)
--profile)Stopping specific profiles
It follows the same logic as starting profiles.
Compose always starts and stops containers in dependency order, where dependencies are determined by:
depends_onlinksvolumes_from
BUT, Compose does not wait until a container is "ready", only until it's running.
This may cause issues if services running inside the container triggers other services that might take some time to start but are critical operationaly speaking.
Detecting "ready" states
Use the condition attribute with one of the following:
service_startedservice_healthy: A dependency is expected to be "healthy", which is defined byhealthcheck.service_completed_successfully: A dependency is expected to run to successful completion before starting a dependent service.
In this case:
dbandredisare created first.Then Compose waits for healthchecks to pass on
db.Healthcheck is done with
pg_isready, retried every 10 seconds up to 5 times.
Then it creates
web.
Don't use env variables to pass sensitive information, use secrets instead.
Compose relies on you to resolve the values. Un-resolved values will lead to the variable being unset and removed.
No warning is raised. (Unless interpolation is used)
You can also temporarily set them on.
Are any piece of data, such as password, certificates, or API keys that shouln't be transmitted over a network or stored unencrypted in a Dockerfile or the applications's source code.
Compose grants access to secrets on a per-service basis.
By default Compose sets up a single network for your application.
The network's name is given based on the project's name, which is based on the name of the directory it lives in OR the project's name given by
--project-name.
Each container for a service joins the default network and is both reachable by other container on that network, and discoverable by the service's name.
This means instead of using the container's name, like it was done with
docker run, withdocker compose upyou will use the service's name.
Avoid referencing containers by IP, since their IPs will change over time when re-created.
Configuring the Default network
Aliases with Links
You can alias the service's name for extra ways to connecting to the container.
This way, you can access the db service from app by the either [db, database].
Creating Custom Networks
To create more complex topologies and specify different network drives and options. Also to connect services to externally-created networks which aren't managed by Compose.
Each service may specify one or more networks to connect to.
Joining External Networks
Compose CLI
The docker compose has a couple of flags that can be used.
--dry-run
Execute commands in dry run mode.
--env-file
Specify an alternate environment file.
-f or --file
Compose configuration files.
--progress
Set thype of progress output. (auto, tty, plain, json, quiet)
--project-directory
Specify an alternate working directory. (default: the path of the, first specified, Compose file)
-p or --project-name
Project name. (/^[a-z0-9]+[a-z0-9\-\_]*/)
docker compose down [OPTIONS] [SERVICES]
Will stop and remove the following, that were created by up :
Containers;
Networks:
The ones defined in
networksection ofcompose.yaml.Networks defined as external are never removed.
Volumes:
Anonymous volumes are not removed by default. (But are also not mounted for subsequent
up)Volumes defined as external are never removed.
Images if flag
--rmiused.
--remove-orphans
Remove containers for services not defined in the Compose file.
--rmi
Removes Images used by services. ("local" remove only images that don't have a custom tag ("local" | "all"))
-t or --timout
Specify a shutdown timout in seconds.
-v or --volumes
Removes named volumes declared in the
volumessection of the Compose file.Removes anonymous volumes attached to containers.
docker compose logs [OPTIONS] [SERVICES]
Display log outputs from services.
docker compose ps [OPTIONS] [SERVICE]
List containers for a Compose project, with current status and exposed ports.
By default, only running containers are shown.
-a or --all
Show all containers. (Including the ones created without Compose)
--format
Format output with custom template. (table, json, TEMPLATE)
--orphans
Include services not declared by project.
docker compose run [OPTIONS] SERVICE [COMMAND] [ARGS...]
Runs a one-time command against a service.
docker compose up [OPTIONS] [SERVICES]
Builds, (re)creates, starts and attaches to containers for a service.
An exit code 1 is generated if the process encounter an error.
If the process was interrupted using SIGINT (Ctrl + C) or SIGTERM, the containters are stopped, and the exit code is 0.
--abort-on-container-exit
Stop all containers if any container was stopped. (Incompatible with -d)
--abort-on-container-failure
Stop all container if any container exited with failure. (Incompatible with -d)
--build
Build Images before starting containers.
-d or --detach
Run containers in the background.
--force-recreate
Recreate containers even if their configuration and Image haven't changed.
--no-attach
Do not attach (stream logs) to specified services.
--no-deps
Do not recreate services linked services. Ex.: If you change a service config, and don't need to rebuild the dependent services.
--no-recreate
Don't recreate containers even if their configuration and Image have changed.
--no-start
Don't start the services after creating them.
--quiet-pull
Pull images without printing progress information.
-V or --renew-anon-volumes
Recreate anonymous volumes instead of retrieving data from the previous containers.
--timestamps
Show timestamps.
--wait
Wait for services to be running|healthy. (Implies detached mode)
--wait-timeout
Maximum duration to wait for project to be running|healthy.
Running
You can run the docker-compose with
docker-compose up.Use
-dto run in detach mode.
You can choose the services/container to go up with:
docker-compose up [list-of-container], likedocker-compose up -d node mysql.
Stopping
You can stop the containers with
docker-compose down.Docker compose will stop and remove the containers, networks and others, BUT NOT the volumes that were created.
Use
-vflag to also delete the volumes.
Choosing a dockerfile from multiple ones
Dependency of Containers
You can specify that a container should only go up if another one went up with
depends_onconfig.This means that if you start with
docker-compoase up -d frontend, it will automaticallyupthebackendcontainer.
Force docker-compose to reevalute the dockerfiles and rebuild if necessary
Front end Containers
Just like it was needed to use the flag
-itin frontend containers, you can config them with:
YAML Tips & Tricks
Some YAML tips when creating the Compose files.
When using anchors, use Map Syntax when providing <key> and <values>. Array Syntax only allows <key>.
Are built-in YAML features, to help create re-usable blocks. (They kind of work like variables, not really..)
From this example, you configure and name the properties from environment as &env (where & symbol states the origin of data), and then reuse them later with *env.
Adding or Overriding values
Pulling more than one anchor
Use the prefix x- as a top-level element to modularize configurations to reuse.
Compose ignores any fields that starts with x-.
This means that you can use it to declare properties on the top of the file (like variables), and then use them inside valid properties (services, networks, ...) with anchors.
Values in Compose file can be set by variables and interpolated at runtime.
Both $VARIABLE and ${VARIABLE} are supported.
Interpolation is mostly for <values>, the only properties that allows you to interpolate on <keys> are labels and environment.
Compose Properties
Some of the top-level properties that can be defined in compose.yaml.
To define the project's name. Can also be set by COMPOSE_PROJECT_NAME default env variable or by -p option in the command line.
service (required)
service (required)A service is an abstract definition of a computing resource, and is backed by a container.
Some attributes a service may declare:
value
Defines how to create the Docker image for the service. (Usually the path to the Dockerfile)
blkio_config
map
Defines a set of configurations to set IO block limits.
command
value
Overrides the default command declared by the container image.
(Ex.: By Dockerfile's CMD)
(If value is '' or [], default command is overwriten to be empty)
container_name
value
For custom container's name. (If defined, may stop Compose from scaling beyond one container)
cpu_count
value
Defines the number of usable CPUs.
cpu_shares
value
As integer value, defines relative CPU weight versus other containers.
array or map
To define dependency to other services. Will also control the order of startup and shutdown.
map
Set of deployment specifications for managing the behavior of containers across different environments.
domainname
value
Custom domain name for the container.
entrypoint
value or array
Overrides the default entrypoint declared by the container image.
(Ex.: By Dockerfile's ENTRYPOINT)
(If value is '' or [], default command is overwriten to be empty)
extra_hosts
array or map
Adds hostname mappings to container's network interface configuration.
Ex.: (/etc/hosts)
hostname
value
Custom hostname for the container.
image
value
Another way to define which image to use. (Like if you don't have a Dockerfile)
mem_limit
value
Limit the amount of memory a container can allocate.
Ex.: (300m, 1gb)
(Must be consistent with limits.memory attribute in deploy attribute)
mem_reservation
value
Reserves an amount of memory a container can allocate.
Ex.: (300m, 1gb)
(Must be consistent with reservations.memory attribute in deploy attribute)
privileged
value
Configures the service to run with elevated priviledges.
tty
value
Configure the service to run with tty.
(Same as running the container with -t flag.
user
value
Overrides the user to run the container process.
(This overwrites the user defined in Dockerfile)
array
Define mount host paths or named volumes assessible by the containers. (For the volume to be reused by multiple services, it must also be declared as top-level)
working_dir
value
Overrides the container's working directory.
(This overrides WORKDIR from Dockerfile)
Check more info over Network up here.
The top-level networks lets you configure named networks that can be reused across multiple services.
Some attributes a service may declare:
driver
value
Specifies the network driver to use.
external
value
Specifies if the network is maintained outside the application.
name
value
Custom name for the network.
The top-level volumes lets you configure named volumes that can be reused across multiple services.
Some attributes a service may declare:
driver
value
Specifies the volume driver to use.
external
value
Specifies if the volume is maintained outside the application.
name
value
Custom name for the volume.
Lets services to adapt their behavior withtout the need to rebuild the Docker Image.
Check more info on the docs.
Check more info over Secrets up here.
The top-level secrets lets you define or reference sensitive data that can be accessed across multiple services.
A secret's source can be either a file or environment.
Last updated