When we want to start a series of interdependent services at the same time, it is particularly tedious to start them one by one and in strict order. This is where we can use docker compose to perform this series of operations.

Compose

Compose is a tool for defining and running multi-container Docker applications. With Compose you can use a YML file to configure all the services your application needs, and then create and start all the services from the YML file configuration with a single command.

Compose uses

  • Use Dockerfile to define the application’s environment.
  • Use docker-compose.yml to define the services that make up the application so they can run together in an isolated environment.
  • Finally, execute the docker-compose up command to start and run the entire application.

demo Dockerfile

1
2
3
4
5
6
7
8
9
FROM python:3.7-alpine
WORKDIR /code
ENV FLASK_APP app.py
ENV FLASK_RUN_HOST 0.0.0.0
RUN apk add --no-cache gcc musl-dev linux-headers
COPY requirements.txt requirements.txt
RUN pip install -r requirements.txt
COPY . .
CMD ["flask", "run"]
  • FROM python:3.7-alpine: Build the image from the Python 3.7 base image.
  • WORKDIR /code: Sets the working directory to /code.
  • ENV FLASK_APP app.py, ENV FLASK_RUN_HOST 0.0.0.0: Set environment variables.
  • COPY requirements.txt requirements.txt, RUN pip install -r requirements.txt: Copies requirements.txt and installs Python dependencies.
  • COPY . .: Copies the . project’s current directory to the . image to the working directory.
  • CMD ["flask", "run"]: The container provides the default execution command as: flask run.

docker-compose.yml

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
version: "3"
services:
  mongo:
    image: mongo:3.4.24-xenial
    command: mongod --port 27017
    ports:
      - "27017:27017"
  demo:
    build: .
    ports:
      - "5000:5000"
    depends_on:
      - mongo

to build and run the service

docker-compose up, followed by the -d argument if you want to run it in the background.

yml configuration reference

version

version: "3" Specifies which version of compose this yml depends on.

build

Specifies the parameters for the build.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
version: "3"
services:
  demo:
    build:
      context: ./dir
      dockerfile: demo/Dockerfile
      args:
        buildno: 1
      labels:
        - "com.example.description=yeqiongzhou demo"
        - "com.example.department=China Shanghai"
        - "com.example.label-with-empty-value"
      target: prod
  • context: Context path.
  • dockerfile: Specify the name of the Dockerfile file where the image will be built.
  • args: Add build arguments, which are environment variables that can only be accessed during the build process.
  • labels: Set the labels for the build image.
  • target: Multi-layer build, you can specify which layer to build.

command

command: ["go", "run", "main.go"] will override the default command specified in the Dockerfile container.

container_name

container_name: yeqiongzhou-demo specifies a custom container name instead of the generated default name.

depends_on

Set dependencies.

  • docker-compose up: Starts services in dependency order. In the following example, db and redis are started first before demo is started.
  • docker-compose up SERVICE: Automatically include dependencies for SERVICE. In the following example, docker-compose up demo will also create and start db and redis.
  • docker-compose stop: Stops the services in dependency order. In the following example, demo stops before db and redis.
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
version: "3"
services:
  demo:
    build: .
    depends_on:
      - db
      - redis
  redis:
    image: redis
  db:
    image: postgres

entrypoint

entrypoint: /code/entrypoint.sh will override the container’s default entrypoint.

environment

Adds an environment variable. You can use arrays or dictionaries, any boolean value, which needs to be enclosed in quotes to ensure that the YML parser will not convert it to True or False.

1
2
3
environment:
  RACK_ENV: development
  SHOW: 'true'

expose

Exposes the port, but does not map it to the host, it is only accessible by the connected service, only the internal port can be specified as an argument.

1
2
3
expose:
  - "6666"
  - "8888"

healthcheck

Check if the docker service is running healthily.

1
2
3
4
5
6
healthcheck:
  test: ["CMD", "curl", "-f", "http://localhost:8888/health"] # Setting up the detection process
  interval: 60s # Set detection interval
  timeout: 10s # Set detection timeout
  retries: 3 # Set the number of retries
  start_period: 30s # How many seconds after startup to start the detection process

image

Specifies the image on which the container is running. The following formats are possible:

  • image: golang
  • image: ubuntu:18.04
  • image: yeqiongzhou/demo
  • image: example-registry.com:5000/redis
  • image: a4bc65fd # image id

logging

Service logging configuration. driver: Specifies the logging driver for the service container, the default value is json-file. three options are available:

  • driver: “json-file”
  • driver: “syslog”
  • driver: “none”

Under the json-file driver only, the following parameters can be used to limit the number and size of logs. When the file limit limit is reached, old files will be deleted automatically.

1
2
3
4
5
logging:
  driver: json-file
  options:
    max-size: "200k" # Single file size of 200k
    max-file: "10" # Maximum 10 files

Under the syslog driver, you can use syslog-address to specify the log receiving address.

1
2
3
4
logging:
  driver: syslog
  options:
    syslog-address: "tcp://192.168.0.1:1024"

restart

  • no: is the default restart policy, the container will not be restarted under any circumstances.
  • always: the container is always restarted.
  • on-failure: restart the container only when the container exits abnormally (exit status is non-zero).
  • unless-stopped: always restart containers when they exit, but disregard containers that were stopped when the Docker daemon was started.

volumes

Mount the host’s data volumes or files to the container.

1
2
3
4
5
6
7
version: "3"
services:
  db:
    image: postgres:latest
    volumes:
      - "/localhost/postgres.sock:/var/run/postgres/postgres.sock"
      - "/localhost/data:/var/lib/postgresql/data"