Docker Compose has a number of non-trivial applications that we will look at in this article. This is another
translation of the article that we analyzed when preparing materials for our Python course for Web development.

Launch order control
Docker Compose runs containers in dependency order, using the depends_on option to specify when the service starts. To determine the startup order, Compose uses depends_on, links, volumes_from and network_mode: "service: ...".
')
If the container must wait for the “ready” state of another container, you can use the wait-for-it or dockerize tools. They will check the hosts and ports until the TCP connection is confirmed. To include a forced wait in the composition, you need to add the entrypoint:
version: '2' services: web: build: . ports: - "80:8000" depends_on: - db entrypoint: "./wait-for-it.sh db:5432" db: image: postgres
You can always write a script wrapper yourself if the need arises for more control.
Running multiple copies of the Compose project
If you need multiple copies of environments with the same composition (or docker-compose.yml file), just run docker-compose up -p new_project_name.
Environment Variables
Shell environment variables can be used to set values in compositions:
Set the environment variables:
$ TAG="latest" $ echo $TAG latest $ DB="postgres" $ echo $DB postgres
Use the environment variable in the Docker Compose file:
db: image: "${DB}:$TAG"
Docker Compose accepts both $ {DB} and $ TAG. You can also set environment variables in containers:
web: environment: - PRODUCTION=1
You can even pass environment variables into containers:
$ PRODUCTION=1 $ echo $PRODUCTION 1
Environment file
To guarantee the transfer of an environment variable, you must store it in an environment file. Name the .env file and save it in the working directory. Docker Compose ignores blank lines (use them for better readability) and code starting with # (that is, comments). You can assign variables for further substitution, as well as set Compose CLI variables:
COMPOSE_API_VERSION COMPOSE_FILE COMPOSE_HTTP_TIMEOUT COMPOSE_PROJECT_NAME DOCKER_CERT_PATH DOCKER_HOST DOCKER_TLS_VERIFY
Sample environment file:
Using multiple Docker Compose files
Use several Docker Compose files if you need to modify the application for different environments (development, intermediate environment and production) or run administration tasks through the Compose application. This provides a way to share common configs.
Docker Compose by default reads two files: docker-compose.yml and docker-compose.override.yml. You can store overrides for existing services in the docker-compose-override.yml file or define new ones. To use multiple files (or a override file with a different name), you must pass -f to docker-compose up (the order matters):
$ docker-compose up -f my-override-1.yml my-overide-2.yml
When the two configuration options match, the new value replaces or expands the original one.
In this example, the new value overwrites the old one and the command starts my_new_app.py:
If environment, labels, volumes, or devices are used, Docker Compose combines the results. In the following example, the three environment variables become FOO = Hello and BAR = “Python Dev!”:
On the development server, we want to open the ports, mount the code as a volume and create a web image (docker-compose.override.yml):
web: build: . volumes: - ".:/code" ports: - "8883:80" environment: DEBUG: "true" db: command: "-d" ports: - "5432:5432" cache: ports: - "6379:6379"
docker-compose up automatically reads the override file and applies it. You will also need the production version of the Docker Compose application, which we call docker-compose.production.yml:
web: ports: - "80:80" environment: PRODUCTION: "true" cache: environment: TTL: "500"
When you need to deploy a production file, simply run the following:
$ docker-compose -f docker-compose.yml -f docker-compose.production.yml up -d
Note: Docker Compose reads docker-compose.production.yml, but not docker-compose.override.yml.
Admin Tasks
You need to run an administrative copy of the application to be able to perform certain tasks, for example, backup a database. Using the already mentioned docker-compose.yml file, create the docker-compose.admin.yml file:
dbadmin: build: database_admin/ links: - db
And then, run the following command:
$ docker-compose -f docker-compose.yml -f docker-compose.admin.yml run dbadmin db-backup
Expansion of services
You can share configurations using the extends field. It also allows sharing options between different projects.
Create common-services.yml (you can name it as you like):
webapp: build: . ports: - "8000:8000" volumes: - "/data"
Create a base docker-compose.yml. For example:
web: extends: file: common-services.yml service: webapp
In addition, you can define (or override) the configuration and add other services locally:
web: extends: file: common-services.yml service: webapp environment: - DEBUG=1 cpu_shares: 5 links: - db important_web: extends: web cpu_shares: 10 db: image: postgres
Common problems
Launch order control
Docker Compose waits only to launch the container before moving on to the next one. In the event that one part of the application becomes unavailable, Docker Compose relies on the flexibility of the rest of the application.
Environment file
If you define environment variables in the shell or via the command line while docker-compose is running, these variables will take precedence over the .env file.
You should not store environment variables in the version control system. If you are using the environment file, add it to the local ignore file and create an env.sample sample, similar to the following example (if it is assumed that the .env file described above is used):
COMPOSE_API_VERSION= # 2 COMPOSE_HTTP_TIMEOUT= # 30 120 DOCKER_CERT_PATH= # EXTERNAL_PORT= # (, 5000 Flask 8000 Django)
Using multiple Docker Compose files
Note that Docker Compose merges files in the order you specified.
Expansion of services
Services never share links, volumes_from or depends_on, using extends; links and volumes_from must always be defined locally.
The end
With questions, suggestions and comments - welcome in the comments. And if you want to speak in real time, join us at
the Open Day of the course.