This page looks best with JavaScript enabled

Packaging a Django Development Environment with Docker from Scratch (3) Docker Compose

 ·  ☕ 6 min read

1. Basic Concepts

Docker Compose is a Docker tool for defining and running complex applications. With Docker Compose, you can define a multi-container application in a single file, then use a single command to start your application and finish all the preparation work.

Docker Compose positions itself as ‘defining and running complex applications with Docker’. Its predecessor was Fig, and it is compatible with Fig template files.

Docker Compose has evolved through three major versions: Version 1, Version 2, and Version 3. If no version is declared, the default is Version 1. Version 1 cannot use the volumes, networks, and build parameters. Version 2 must be declared in the version, and all services must be declared under the service keyword. Version 3 removed the volume_driver, volumes_from, cpu_shares, cpu_quota, cpuset, mem_limit, memswap_limit, extends, and group_add keywords, added deploy, and fully supports Swarm mode. For a more detailed comparison, see the reference links.

This article mainly uses Version 2 as an example to study Docker Compose container orchestration.

2. How It Works

Docker Compose divides the containers it manages into three layers: project, service, and container (contaienr). All files in the directory where Docker Compose runs (docker-compose.yml, extends files, environment variable files, and so on) form a project; unless otherwise specified, the project name is the current directory name.

A project can contain multiple services, and each service defines the image, parameters, and dependencies for running containers. A service can contain multiple container instances, but Docker Compose does not solve the load balancing problem, so other tools are needed to implement service discovery and load balancing.

The project configuration file for Docker Compose defaults to docker-compose.yml. You can customize the configuration file through the COMPOSE_FILE environment variable or the -f parameter, which defines multiple services with dependencies and the containers each service runs. Below is a simple configuration file:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
version: '2'
services:
    web:
        build: .
        ports:
          - "80:90"
        volumes:
          - .:/code
        links:
          - redis
    redis:
        image: redis

It defines two services, web and redis. The web service’s image needs to be built in real time from the Dockerfile in the current directory; at runtime its container needs to expose port 80 on the host and map it to container port 90, and mount the storage volume /code as well as associate the service redis. The redis service is started from the redis image.

Docker Compose is implemented in Python. It calls the docker-py library (see
https://github.com/docker/docker-py ) to communicate with the docker engine, building docker images, starting and stopping docker containers, and so on. The docker-py library calls the docker remote API (see
https://docs.docker.com/reference/api/docker_remote_api/ ) to communicate with the Docker Daemon. You can configure the address of a local or remote Docker Daemon through DOCKER_HOST.

3 Docker Compose Common Commands

CommandExplanation
docker-compose buildBuild the images for the services in the yml
docker-compose psView the status of the services that have been started
docker-compose killStop a service
docker-compose logsView the log of a service
docker-compose portPrint the bound public port
docker-compose pullPull service images
docker-compose upStart all services defined in the yml
docker-compose stopStop all services defined in the yml
docker-compose startStart all stopped services in the yml
docker-compose killForce-stop all services defined in the yml
docker-compose rmRemove all services defined in the yml
docker-compose restartRestart all services defined in the yml
docker-compose scaleScale the number of instances of a service, up or down
docker-compose versionView the compose version

4. Common YAML Keywords

4.1 build

Specify the path to the folder containing the Dockerfile (it can be an absolute path, or a path relative to the docker-compose.yml file). Compose will use it to build the image automatically, then use that image.

1
build: /path/to/build/dir

4.2 command

Override the default command executed after the container starts.

1
command: echo "hello world"

4.3 dockerfile

If you need to specify an additional Dockerfile for building the image, you can use this directive. For example:

1
dockerfile: Dockerfile-alternate

Note that this directive cannot be used together with image, otherwise Compose will not know which directive to use to produce the final service image.

4.4 env_file

Get environment variables from a file; it can be a single file path or a list.

If you specify the Compose template file through docker-compose -f FILE, the paths of the variables in env_file are relative to the template file path.

If a variable name conflicts with the environment directive, then by convention the latter wins.

1
2
3
4
5
6
env_file: .env

env_file:
  - ./common.env
  - ./apps/web.env
  - /opt/secrets.env

Each line in the environment variable file must conform to the format, and comment lines starting with # are supported.

1
2
# common.env: Set development environment
PROG_ENV=development

4.5 environment

Set environment variables. You can use either array or dictionary format.

A variable given with only a name automatically takes the value of the corresponding variable on the host running Compose, which can be used to prevent leaking unnecessary data. For example:

1
2
3
environment:
  RACK_ENV: development
  SESSION_SECRET:

Or

1
2
3
environment:
  - RACK_ENV=development
  - SESSION_SECRET

Note that if the variable name or value uses words expressing boolean meaning such as true|false, yes|no, it is best to put them in quotes, to avoid YAML automatically parsing certain content into the corresponding boolean semantics.

http://yaml.org/type/bool.html lists these specific words, including

1
2
3
y|Y|yes|Yes|YES|n|N|no|No|NO
|true|True|TRUE|false|False|FALSE
|on|On|ON|off|Off|OFF

4.6 expose

Expose ports, but do not map them to the host; they are only accessible by linked services. Only internal ports can be specified as parameters.

1
2
3
expose:
 - "3000"
 - "8000"

4.7 image

Specify an image name or image ID. If the image does not exist locally, Compose will try to pull it. For example:

1
2
3
image: ubuntu
image: orchardup/postgresql
image: a4bc65fd

Link to containers in other services. You can use the service name (which also serves as the alias) or the service name:service alias (SERVICE:ALIAS) format.

1
2
3
4
links:
 - db
 - db:database
 - redis

The aliases used will automatically be created in /etc/hosts in the service container. For example:

1
2
3
172.17.2.186  db
172.17.2.186  database
172.17.2.187  redis

The corresponding environment variables in the linked container will also be created.

4.9 volumes

Set the mount path for data volumes. You can set a host path (HOST:CONTAINER) or add an access mode (HOST:CONTAINER:ro). Paths in this directive support relative paths. For example

1
2
3
4
volumes:
 - /var/lib/mysql
 - cache/:/tmp/cache
 - ~/configs:/etc/configs/:ro

4.10 volumes_from

Mount its data volumes from another service or container.

1
2
3
volumes_from:
 - service_name
 - container_name

5. References


微信公众号
WRITTEN BY
微信公众号