[Docker series] Docker Compose

Posted by TangoGirl on Mon, 24 Jan 2022 22:56:15 +0100

Docker Compose introduction

Simplify the deployment steps and define the container, network, port and other information we need to start through a YAML format file.

There are docker compose command tools to start and stop operations.

Installation of docker compose

After docker desktop is installed by default for Windows and Mac, docker compose is automatically installed

PS F:\docker>  docker-compose --version
docker-compose version 1.29.2, build 5becea4c

Linux users need to install it themselves

The latest version number can be queried here https://github.com/docker/compose/releases

$ sudo curl -L "https://github.com/docker/compose/releases/download/1.29.2/docker-compose-$(uname -s)-$(uname -m)" -o /usr/local/bin/docker-compose
$ sudo chmod +x /usr/local/bin/docker-compose
$ docker-compose --version
docker-compose version 1.29.2, build 5becea4c

Friends who are familiar with python can use pip to install docker compose
Because it is a tool written in Python

$ pip install docker-compose

Structure and version of compose file

Syntax description of docker compose file (please save the frequently used links): https://docs.docker.com/compose/compose-file/

Basic grammatical structure

version: "3.8"

services: # container
  servicename: # Service name, which is also the DNS name that can be used by the internal bridge network
    image: # Image name
    command: # Optional. If set, the CMD command in the default image will be overwritten
    environment: # Optional, equivalent to -- env in docker run
    volumes: # Optional, equivalent to - v in docker run
    networks: # Optional, equivalent to -- network in docker run
    ports: # Optional, equivalent to - p in docker run
  servicename2:

volumes: # Optional, equivalent to docker volume create

networks: # Optional, equivalent to docker network create

with Python Flask + Redis exercise : as an example, transform it into a docker compose file

docker image pull redis
docker image build -t flask-demo .

# create network
docker network create -d bridge demo-network

# create container
docker container run -d --name redis-server --network demo-network redis
docker container run -d --network demo-network --name flask-demo --env REDIS_HOST=redis-server -p 5000:5000 flask-demo

docker-compose. The YML file is as follows:

version: "3.8"

services:
  flask-demo:
    image: flask-demo:latest
    environment:
      - REDIS_HOST=redis-server
    networks:
      - demo-network
    ports:
      - 8080:5000

  redis-server:
    image: redis:latest
    networks:
      - demo-network

networks:
  demo-network:

Docker compose Syntax version

Backward compatibility

Please refer to the official website: https://docs.docker.com/compose/compose-file/

docker compose basic commands

PS F:\docker> docker-compose help
Define and run multi-container applications with Docker.

Usage:
  docker-compose [-f <arg>...] [--profile <name>...] [options] [--] [COMMAND] [ARGS...]
  docker-compose -h|--help

Options:
  -f, --file FILE             Specify an alternate compose file
                              (default: docker-compose.yml)
  -p, --project-name NAME     Specify an alternate project name
                              (default: directory name)
  --profile NAME              Specify a profile to enable
  -c, --context NAME          Specify a context name
  --verbose                   Show more output
  --log-level LEVEL           Set log level (DEBUG, INFO, WARNING, ERROR, CRITICAL)
  --ansi (never|always|auto)  Control when to print ANSI control characters
  --no-ansi                   Do not print ANSI control characters (DEPRECATED)
  -v, --version               Print version and exit
  -H, --host HOST             Daemon socket to connect to

  --tls                       Use TLS; implied by --tlsverify
  --tlscacert CA_PATH         Trust certs signed only by this CA
  --tlscert CLIENT_CERT_PATH  Path to TLS certificate file
  --tlskey TLS_KEY_PATH       Path to TLS key file
  --tlsverify                 Use TLS and verify the remote
  --skip-hostname-check       Don't check the daemon's hostname against the
                              name specified in the client certificate
  --project-directory PATH    Specify an alternate working directory
                              (default: the path of the Compose file)
  --compatibility             If set, Compose will attempt to convert keys
                              in v3 files to their non-Swarm equivalent (DEPRECATED)
  --env-file PATH             Specify an alternate environment file

Commands:
  build              Build or rebuild services
  config             Validate and view the Compose file
  create             Create services
  down               Stop and remove resources
  events             Receive real time events from containers
  exec               Execute a command in a running container
  help               Get help on a command
  images             List images
  kill               Kill containers
  logs               View output from containers
  pause              Pause services
  port               Print the public port for a port binding
  ps                 List containers
  pull               Pull service images
  push               Push service images
  restart            Restart services
  rm                 Remove stopped containers
  run                Run a one-off command
  scale              Set number of containers for a service
  start              Start services
  stop               Stop services
  top                Display the running processes
  unpause            Unpause services
  up                 Create and start containers
  version            Show version information and quit

Start the command docker compose up

Start the command. Currently, there is docker compose YML file

PS F:\docker> docker-compose up
Starting docker_flask-demo_1   ... done                                                                                 Starting docker_redis-server_1 ... done                                                                                 Attaching to docker_redis-server_1, docker_flask-demo_1
redis-server_1  | 1:C 20 Jan 2022 19:17:09.174 # oO0OoO0OoO0Oo Redis is starting oO0OoO0OoO0Oo
redis-server_1  | 1:C 20 Jan 2022 19:17:09.174 # Redis version=6.2.6, bits=64, commit=00000000, modified=0, pid=1, just started
redis-server_1  | 1:C 20 Jan 2022 19:17:09.174 # Warning: no config file specified, using the default config. In order to specify a config file use redis-server /path/to/redis.conf
redis-server_1  | 1:M 20 Jan 2022 19:17:09.174 * monotonic clock: POSIX clock_gettime
redis-server_1  | 1:M 20 Jan 2022 19:17:09.175 * Running mode=standalone, port=6379.
redis-server_1  | 1:M 20 Jan 2022 19:17:09.175 # Server initialized
redis-server_1  | 1:M 20 Jan 2022 19:17:09.175 # WARNING overcommit_memory is set to 0! Background save may fail under low memory condition. To fix this issue add 'vm.overcommit_memory = 1' to /etc/sysctl.conf and then reboot or run the command 'sysctl vm.overcommit_memory=1' for this to take effect.
redis-server_1  | 1:M 20 Jan 2022 19:17:09.175 * Loading RDB produced by version 6.2.6
redis-server_1  | 1:M 20 Jan 2022 19:17:09.175 * RDB age 304 seconds
redis-server_1  | 1:M 20 Jan 2022 19:17:09.175 * RDB memory usage when created 0.77 Mb
redis-server_1  | 1:M 20 Jan 2022 19:17:09.175 # Done loading RDB, keys loaded: 0, keys expired: 0.
redis-server_1  | 1:M 20 Jan 2022 19:17:09.175 * DB loaded from disk: 0.000 seconds
redis-server_1  | 1:M 20 Jan 2022 19:17:09.175 * Ready to accept connections
flask-demo_1    |  * Serving Flask app 'app.py' (lazy loading)
flask-demo_1    |  * Environment: production
flask-demo_1    |    WARNING: This is a development server. Do not use it in a production deployment.
flask-demo_1    |    Use a production WSGI server instead.
flask-demo_1    |  * Debug mode: off
flask-demo_1    |  * Running on all addresses.
flask-demo_1    |    WARNING: This is a development server. Do not use it in a production deployment.
flask-demo_1    |  * Running on http://172.19.0.2:5000/ (Press CTRL+C to quit)

Background start

PS F:\docker> docker-compose up -d
Starting docker_flask-demo_1   ... done
Starting docker_redis-server_1 ... done
PS F:\docker>

View docker compose logs

You can view the log after - d

PS F:\docker> docker-compose logs

Continuously and dynamically view logs

PS F:\docker> docker-compose logs -f

View the service docker compose PS defined in the background

It needs to be in docker compose Run this command from the YML file, otherwise:

ERROR:
Can't find a suitable configuration file in this directory or any
parent. Are you in the right directory?
Supported filenames: docker-compose.yml, docker-compose.yaml, compose.yml, compose.yaml

PS F:\docker> docker-compose ps
        Name                       Command               State           Ports
---------------------------------------------------------------------------------------
docker_flask-demo_1     flask run -h 0.0.0.0             Up      0.0.0.0:8080->5000/tcp
docker_redis-server_1   docker-entrypoint.sh redis ...   Up      6379/tcp

Note: the default is docker compose YML file, other names need to be specified with - f

Options:
 -f, --file FILE             Specify an alternate compose file
                             (default: docker-compose.yml)

Delete docker compose RM

Docker compose in exit status will be deleted directly

PS F:\docker> docker-compose rm
Going to remove docker_redis-server_1, docker_flask-demo_1
Are you sure? [yN] y
Removing docker_redis-server_1 ... done                                                                                 Removing docker_flask-demo_1   ... done                                                                                

Specify docker compose name (prefix) docker compose - P {name} up

Specify name action:

PS F:\docker> docker-compose -p myproject up -d
Starting myproject_flask-demo_1 ...
Starting myproject_flask-demo_1 ... done                                                                                PS F:\docker> docker-compose -p myproject rm
No stopped containers
PS F:\docker> docker-compose -p myproject stop
Stopping myproject_redis-server_1 ... done                                                                              Stopping myproject_flask-demo_1   ... done                                                                              PS F:\docker> docker-compose -p myproject rm
Going to remove myproject_redis-server_1, myproject_flask-demo_1
Are you sure? [yN] y
Removing myproject_redis-server_1 ... done                                                                              Removing myproject_flask-demo_1   ... done                                                                              PS F:\docker>

Docker compose custom container name

The custom container name is myflask Demo: container_ name: myflask-demo

version: "3.8"

services:
  flask-demo:
  	container_name: myflask-demo # Custom container name
    image: flask-demo:latest
    environment:
      - REDIS_HOST=redis-server
    networks:
      - demo-network
    ports:
      - 8080:5000

  redis-server:
    image: redis:latest
    networks:
      - demo-network

networks:
  demo-network:

Docker compose image construction and pull

structure

When the image does not exist, you will pull the image, but how to build a customized image docker compose?

Put the app Put py and Dockerfile files into flash

Modify the original YML file docker-compose1 yml:
Build write directory, used to build the image

version: "3.8"

services:
  flask-demo:
    build: ./flask # Built directory
    environment:
      - REDIS_HOST=redis-server
    networks:
      - demo-network
    ports:
      - 8080:5000

  redis-server:
    image: redis:latest
    networks:
      - demo-network

networks:
  demo-network:

Direct create startup

PS F:\docker> docker-compose -f .\docker-compose1.yml up
Building flask-demo
Sending build context to Docker daemon  3.072kB
Step 1/8 : FROM python:3.9.5-slim
 ---> c71955050276
Step 2/8 : RUN pip install flask redis &&     groupadd -r flask && useradd -r -g flask flask &&     mkdir /src &&     chown -R flask:flask /src
 ---> Running in 2fb3ac9af1c1
Collecting flask
  Downloading Flask-2.0.2-py3-none-any.whl (95 kB)
Collecting redis
  Downloading redis-4.1.1-py3-none-any.whl (173 kB)
Collecting click>=7.1.2
  Downloading click-8.0.3-py3-none-any.whl (97 kB)
Collecting Jinja2>=3.0
  Downloading Jinja2-3.0.3-py3-none-any.whl (133 kB)
Collecting itsdangerous>=2.0
  Downloading itsdangerous-2.0.1-py3-none-any.whl (18 kB)
Collecting Werkzeug>=2.0
  Downloading Werkzeug-2.0.2-py3-none-any.whl (288 kB)
Collecting MarkupSafe>=2.0
  Downloading MarkupSafe-2.0.1-cp39-cp39-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl (30 kB)
Collecting packaging>=20.4
  Downloading packaging-21.3-py3-none-any.whl (40 kB)
Collecting deprecated>=1.2.3
  Downloading Deprecated-1.2.13-py2.py3-none-any.whl (9.6 kB)
Collecting wrapt<2,>=1.10
  Downloading wrapt-1.13.3-cp39-cp39-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl (81 kB)
Collecting pyparsing!=3.0.5,>=2.0.2
  Downloading pyparsing-3.0.6-py3-none-any.whl (97 kB)
Installing collected packages: wrapt, pyparsing, MarkupSafe, Werkzeug, packaging, Jinja2, itsdangerous, deprecated, click, redis, flask
Successfully installed Jinja2-3.0.3 MarkupSafe-2.0.1 Werkzeug-2.0.2 click-8.0.3 deprecated-1.2.13 flask-2.0.2 itsdangerous-2.0.1 packaging-21.3 pyparsing-3.0.6 redis-4.1.1 wrapt-1.13.3
WARNING: Running pip as the 'root' user can result in broken permissions and conflicting behaviour with the system package manager. It is recommended to use a virtual environment instead: https://pip.pypa.io/warnings/venv
WARNING: You are using pip version 21.1.3; however, version 21.3.1 is available.
You should consider upgrading via the '/usr/local/bin/python -m pip install --upgrade pip' command.
Removing intermediate container 2fb3ac9af1c1
 ---> da32b83af27e
Step 3/8 : USER flask
 ---> Running in 557bf0bb9d88
Removing intermediate container 557bf0bb9d88
 ---> 374c6b5f462e
Step 4/8 : COPY app.py /src/app.py
 ---> 5fc4e5b60e75
Step 5/8 : WORKDIR /src
 ---> Running in fa96d8ba41d3
Removing intermediate container fa96d8ba41d3
 ---> 7c90c225ab3e
Step 6/8 : ENV FLASK_APP=app.py REDIS_HOST=redis
 ---> Running in a84c16facb22
Removing intermediate container a84c16facb22
 ---> 8b54841afbf4
Step 7/8 : EXPOSE 5000
 ---> Running in 2b5744ca4e4c
Removing intermediate container 2b5744ca4e4c
 ---> 41d9b9cb3649
Step 8/8 : CMD ["flask", "run", "-h", "0.0.0.0"]
 ---> Running in 780790c05526
Removing intermediate container 780790c05526
 ---> 9b1341debf58
Successfully built 9b1341debf58
Successfully tagged docker_flask-demo:latest
SECURITY WARNING: You are building a Docker image from Windows against a non-Windows Docker host. All files and directories added to build context will have '-rwxr-xr-x' permissions. It is recommended to double check and reset permissions for sensitive files and directories.

Use 'docker scan' to run Snyk tests against images to find vulnerabilities and learn how to fix them
WARNING: Image for service flask-demo was built because it did not already exist. To rebuild this image you must use `docker-compose build` or `docker-compose up --build`.
Creating docker_flask-demo_1   ... done                                                                                 Creating docker_redis-server_1 ... done                                                                                 Attaching to docker_redis-server_1, docker_flask-demo_1
redis-server_1  | 1:C 20 Jan 2022 19:53:22.062 # oO0OoO0OoO0Oo Redis is starting oO0OoO0OoO0Oo
redis-server_1  | 1:C 20 Jan 2022 19:53:22.062 # Redis version=6.2.6, bits=64, commit=00000000, modified=0, pid=1, just started
redis-server_1  | 1:C 20 Jan 2022 19:53:22.062 # Warning: no config file specified, using the default config. In order to specify a config file use redis-server /path/to/redis.conf
redis-server_1  | 1:M 20 Jan 2022 19:53:22.062 * monotonic clock: POSIX clock_gettime
redis-server_1  | 1:M 20 Jan 2022 19:53:22.063 * Running mode=standalone, port=6379.
redis-server_1  | 1:M 20 Jan 2022 19:53:22.063 # Server initialized
redis-server_1  | 1:M 20 Jan 2022 19:53:22.063 # WARNING overcommit_memory is set to 0! Background save may fail under low memory condition. To fix this issue add 'vm.overcommit_memory = 1' to /etc/sysctl.conf and then reboot or run the command 'sysctl vm.overcommit_memory=1' for this to take effect.
redis-server_1  | 1:M 20 Jan 2022 19:53:22.064 * Ready to accept connections
flask-demo_1    |  * Serving Flask app 'app.py' (lazy loading)
flask-demo_1    |  * Environment: production
flask-demo_1    |    WARNING: This is a development server. Do not use it in a production deployment.
flask-demo_1    |    Use a production WSGI server instead.
flask-demo_1    |  * Debug mode: off
flask-demo_1    |  * Running on all addresses.
flask-demo_1    |    WARNING: This is a development server. Do not use it in a production deployment.
flask-demo_1    |  * Running on http://172.19.0.2:5000/ (Press CTRL+C to quit)

View local mirror:

PS F:\docker> docker image ls
REPOSITORY          TAG          IMAGE ID       CREATED         SIZE
docker_flask-demo   latest       9b1341debf58   2 minutes ago   129MB

Custom Dockerfile

The default is to find the Dockerfile file. If there is no Dockerfile file, an error will be reported

This requires adding parameters:
context: specified directory
Dockerfile: Custom dockerfile file name

version: "3.8"

services:
  flask-demo:
    build: 
      context: ./flask # Specified directory
      dockerfile: Dockerfile-flask.txt  # Custom Dockerfile file name
    environment:
      - REDIS_HOST=redis-server
    networks:
      - demo-network
    ports:
      - 8080:5000

  redis-server:
    image: redis:latest
    networks:
      - demo-network

networks:
  demo-network:

Pull docker compose pull

Prepare the image in advance, and the construction will be fast

docker-compose pull

Topics: Operation & Maintenance Docker Container