Small knowledge, big challenge! This article is participating in the creation activity of “Essential Tips for Programmers”.
This article has participated in the “Digitalstar Project” and won a creative gift package to challenge the creative incentive money.
Docker advanced | Docker Compose
background
Previously through DockerFile using Docker Build command to generate images through Docker Run, are manually to operate and is a single container. If there are 100 microservices and they all have dependencies, how do we maintain them? Docker Compose makes it easy and efficient to manage containers. Defining and running multiple containers
The official introduction
-
Compose is a program that defines and runs multiple containers.
-
The Yaml File configuration file is required
-
Single command command
Compose is a tool for defining and running multi-container Docker applications. With Compose, you use a YAML file to configure your application’s services. Then, with a single command, you create and start all the services from your configuration. To learn more about all the features of Compose, see the list of features.
Docker Compose is available for all environments
Compose works in all environments: production, staging, development, testing, as well as CI workflows. You can learn more about each case in Common Use Cases.
Using the step
Using Compose is basically a three-step process:
- Define your app’s environment with a
Dockerfile
so it can be reproduced anywhere.- Dockerfile ensures that our project can run anywhere
- Define the services that make up your app in
docker-compose.yml
so they can be run together in an isolated environment.-
What is a service?
-
Docker-comemage. yml docker-comemage. yml
-
- Run
docker compose up
and the Docker compose command starts and runs your entire app. You can alternatively rundocker-compose up
using the docker-compose binary.- Start the project
Purpose: Batch container orchestration.
Compose is an official Docker open source project, a standalone project that requires installation
Dockerfile lets programs run anywhere. For Web services, redis,mysql,nginx, multiple containers, we can write a Compose file and bundle these services in bulk
docker-compose.yml
version: "3.9" # optional since v1.27.0
services:
web:
build: .
ports:
- "5000:5000"
volumes:
- .:/code
- logvolume01:/var/log
links:
- redis
redis:
image: redis
volumes:
logvolume01: {}
Copy the code
Docker-compose up brings all services online in one click
Compose: important concept
- Compose is used for orchestration of services, applications (Web, Redis,mysql)
- The project of the project. An associated set of containers
The installation
-
download
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 # backup address: domestic mirror sudo curl -L "https://get.daocloud.io/docker/compose/releases/download/1.29.2/docker-compose-$(uname -s)-$(uname -m)" -o /usr/local/bin/docker-compose % Total % Received % Xferd Average Speed Time Time Time Current Dload Upload Total Spent Left Speed 100 423 100 423 00 177 0 0:00:02 0:00:02 --:--:-- 177 100 12.1m 100 12.1m 00 3832K 0 0:00:03 0:00:03 --:--:-- 31.4m# View download results $ cd /usr/local/bin [root@VM-8-10-centos ~]# cd /usr/local/bin [root@VM-8-10-centos bin]# ll12476-rwxr-xr-x 1 root root 383 12月 10 2019 chardetect-rwxr-xr-x 1 root root 389 12月 10 2019 cloud-init-rwxr-xr-x 1 root root 1781 12月 10 2019 cloud-init-per-rw-r --r-- 1 root root 12737304 10月 1 14:26 docker-compose# Download successful Copy the code
-
authorization
$ sudo chmod +x /usr/local/bin/docker-compose # authorization $ docker-compose version Test the installation resultsDocker-compose version 1.29.2, build 5becea4C docker-py version: 5.0.0 CPython version: 3.7.10 OpenSSL version: OpenSSL 1.1.0L 10 Sep 2019# Install successfully Copy the code
experienceGet started
Python applications: counters, counting using Redis
1.Setup : Define the application dependencies
The dependency files needed to create the project ~
Create project storage directory
$ cd ~
$ mkdir app
$ cd app
# Create project file Aki
$ mkdir composetest
$ cd composetest
# create app.py file
$ vim app.py The source code is below
Create requirements. TXT to write the required dependencies for the project
$ vim requirements.txt
Copy the code
app.py
import time
import redis
from flask import Flask
app = Flask(__name__)
cache = redis.Redis(host='redis', port=6379)
def get_hit_count() :
retries = 5
while True:
try:
return cache.incr('hits')
except redis.exceptions.ConnectionError as exc:
if retries == 0:
raise exc
retries -= 1
time.sleep(0.5)
@app.route('/')
def hello() :
count = get_hit_count()
return 'Hello World! I have been seen {} times.\n'.format(count)
Copy the code
requirements.txt
flask
redis
Copy the code
2.Create a Dockerfile
Create Dockerfile
$ vim Dockerfile
Copy the code
Dockerfile
# syntax=docker/dockerfile:1
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
EXPOSE 5000
COPY.
CMD ["flask"."run"]
Copy the code
3.Define services in a Compose file
Define the service in Compose
vim docker-compose.yml
Copy the code
docker-compose.yml
version: "3.9"
services:
web:
build: .
ports:
- "5000:5000"
redis:
image: "redis:alpine"
Copy the code
4.Build and run your app with Compose
Build & Run our app
$ docker-compose up
# or
$ docker-compose up -d # background bootBuilding Web Sending build context to Docker Daemon 5.632kB Step 1/10: FROM python:3.7-alpine --> a436fb2c575c Step 2/10: WORKDIR /code --> Using cache --> 02545a7b7f7c Step 3/10: ENV FLASK_APP=app.py ---> Using cache ---> ed7fe3f6c9c6 Step 4/10 : ENV FLASK_RUN_HOST=0.0.0.0 --> Using cache --> 80ea3d59f3f4 Step 5/10: RUN apk add --no-cache gcc musl-dev linux-headers ---> RunninginD2e239100b80 fetch https://dl-cdn.alpinelinux.org/alpine/v3.14/main/x86_64/APKINDEX.tar.gz ^ CGracefully stopping... (press Ctrl+C again to force) [root@VM-8-10-centos composetest]# ^C
[root@VM-8-10-centos composetest]# clear
[root@VM-8-10-centos composetest]# sudo docker-compose up Sudo: docker-compose: command not found [root@VM-8-10-centos composetest]# su docker-compose up Su: docker-compose does not exist [root@VM-8-10-centos composetest]# docker-compose up Building Web Sending build context to Docker Daemon 5.632kB Step 1/10: FROM python:3.7-alpine --> a436fb2c575c Step 2/10: WORKDIR /code --> Using cache --> 02545a7b7f7c Step 3/10: ENV FLASK_APP=app.py ---> Using cache ---> ed7fe3f6c9c6 Step 4/10 : ENV FLASK_RUN_HOST=0.0.0.0 --> Using cache --> 80ea3d59f3f4 Step 5/10: RUN apk add --no-cache gcc musl-dev linux-headers ---> Runningin7 d9a832e54e3 fetch https://dl-cdn.alpinelinux.org/alpine/v3.14/main/x86_64/APKINDEX.tar.gz fetch https://dl-cdn.alpinelinux.org/alpine/v3.14/community/x86_64/APKINDEX.tar.gz (1/13) Installing libgcc (10.3.1_git20210424-r2) (2/13) Installing libstdc++ (10.3.1_git20210424-r2) (3/13) Installing binutils (2.35.2-r2) (4/13) Installing libgomp (10.3.1_GIT20210424-R2) (5/13) Installing libatomic (10.3.1_GIT20210424-R2) (6/13 Libgphobos (10.3.1_gIT20210424-R2) (7/13) Installing GMP (6.2.1-R0) (8/13) Installing ISL22 (0.22-R0) (9/13 Mpfr4 (4.1.0-R0) (10/13) Installing MPC1 (1.2.1-R0) (11/13) Installing GCC (10.3.1_GIT20210424-R2) (12/13) Linux-headers (5.10.41-R0) (13/13) Installing MUSl-dev (1.2.2-R3) Executing BUSyBOX-1.33.1-R3. Trigger OK: 140 MiBin 48 packages
Removing intermediate container 7d9a832e54e3
---> c6b8ad3388a1
Step 6/10 : COPY requirements.txt requirements.txt
---> b25eb321aea3
Step 7/10 : RUN pip install -r requirements.txt
---> Running inC9b03beaca70 Collecting Flask Downloading flask -2.0.1-Py3-None-any. WHL (94 kB) Collecting Redis Downloading Collecting Jinja2>= Downloading jinja2-3.0.1-py3-none-any. WHL (50 kB) Downloading jinja2-3.0.1-py3-none-any. WHL (50 kB) Downloading Jinja2-3.0.1-py3-none-any. WHL (50 kB) Downloading Jinja2-3.0.1-py3-none-any. WHL (50 kB) Downloading Jinja2-3.0.1-py3-none-any. WHL (50 kB) Collecting click>=7.1.2 Downloading click-8.0.1-py3-none-any. WHL (97 kB) Downloading Werkzeug>=2.0 Downloading Werkzeug-2.0.1-py3-none-any.whl (288 kB) Collecting itsDangerous >=2.0 Downloading itsDangerous-2.0.1-py3-none-any.whL (18 kB) Collecting importlib - metadata Downloading importlib_metadata 4.8.1 - py3 - none - any. WHL (17 kB) Collecting MarkupSafe>=2.0 Downloading Markupsafe-2.0.1.tar. gz (18 kB) Collecting typing-Extensions >=3.6.4 Downloading Typing_extensions 3.10.0.2 - py3 - none - any. WHL (26 kB) Collecting zipp > = 0.5 Downloading zipp 3.6.0 - py3 - none - any. WHL (5.3) kB) Building wheelsfor collected packages: MarkupSafe
Building wheel for MarkupSafe (setup.py): started
Building wheel for MarkupSafe (setup.py): finished with status 'done'
Created wheel forMarkupSafe: Filename = MarkupSafe - 2.0.1 cp37 - cp37m - linux_x86_64. WHL size = 14616 sha256=a2be1498a2fa606910a87342770f0f777eb9ce4a73a209969fbded2bfb5bd0b5 Storedindirectory: /root/.cache/pip/wheels/1a/18/04/e3b5bd888f000c2716bccc94a565239f9defc47ef93d9e7bea Successfully built MarkupSafe Installing collected packages: zipp, typing-extensions, MarkupSafe, importlib-metadata, Werkzeug, Jinja2, itsdangerous, click, redis, Flask Successfully installed jinjA2-3.0.1 markupsafe-2.0.1 werkzeug-2.0.1 click-8.0.1 flask-2.0.1 Importlib-metadata-4.8.1 itsDangerous -2.0.1 redis-3.5.3 typing-extensions-3.10.0.2 zipp-3.6.0 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
Removing intermediate container c9b03beaca70
---> 6ca85fbb3685
Step 8/10 : EXPOSE 5000
---> Running in 58a8698ea25a
Removing intermediate container 58a8698ea25a
---> 313ecb8fbfbd
Step 9/10 : COPY . .
---> 11705881d5c4
Step 10/10 : CMD ["flask"."run"]
---> Running ine2c0d681ab04 Removing intermediate container e2c0d681ab04 ---> e1a776378e7e Successfully built e1a776378e7e Successfully tagged composetest_web:latest WARNING: Imagefor service web was built because it did not already exist. To rebuild this image you must use `docker-compose build` or `docker-compose up --build`.
Pulling redis (redis:alpine)...
alpine: Pulling from library/redis
a0d0a0d46f8b: Already exists
a04b0375051e: Pull complete
cdc2bb0f9590: Pull complete
8f19735ec10c: Pull complete
ac5156a4c6ca: Pull complete
7b7e1b3fdb00: Pull complete
Digest: sha256:fa785f9bd167b94a6b30210ae32422469f4b0f805f4df12733c2f177f500d1ba
Status: Downloaded newer image for redis:alpine
Creating composetest_web_1 ... done
Creating composetest_redis_1 ... doneAttaching to composetest_redis_1, composetest_web_1 redis_1 | 1: C 06:59:57 of the Oct 11th, 2021. 739# oO0OoO0OoO0Oo Redis is starting oO0OoO0OoO0OoRedis_1 | 1: C 06:59:57 of the Oct 11th, 2021. 739# Redis version=6.2.5, bits=64, commit=00000000, Modified =0, PID =1, just startedRedis_1 | 1: C 06:59:57 of the Oct 11th, 2021. 739# Warning: no config file specified, using the default config. In order to specify a config file use redis-server /path/to/redis.confRedis_1 | 1: M 06:59:57 of the Oct 11th, 2021. 740 * monotonic clock: POSIX clock_gettime redis_1 | 1: M 06:59:57 of the Oct 11th, 2021. 741 * Running mode = standalone, Port = 6379. Redis_1 | 1: M 06:59:57 of the Oct 11th, 2021. 741# WARNING: The TCP backlog setting of 511 cannot be enforced because /proc/sys/net/core/somaxconn is set to the lower value of 128.Redis_1 | 1: M 06:59:57 of the Oct 11th, 2021. 741# Server initializedRedis_1 | 1: M 06:59:57 of the Oct 11th, 2021. 741# 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_1 | 1: M 06:59:57 of the Oct 11th, 2021. 741 * Ready to accept connections web_1 | * Serving Flask app'app.py' (lazy loading)
web_1 | * Environment: production
web_1 | WARNING: This is a development server. Do not use it in a production deployment.
web_1 | Use a production WSGI server instead.
web_1 | * Debug mode: off
web_1 | * Running on all addresses.
web_1 | WARNING: This is a development server. Do not use it inA production deployment. Web_1 | * Running on http://172.19.0.3:5000/ (Press CTRL + C to quit)# Startup succeeded
Copy the code
[root@VM-8-10-centos composetest]# curl localhost:5000
Hello World! I have been seen 2 times.
[root@VM-8-10-centos composetest]# curl localhost:5000
Hello World! I have been seen 3 times.
[root@VM-8-10-centos composetest]# curl localhost:5000
Hello World! I have been seen 4 times.
[root@VM-8-10-centos composetest]# curl localhost:5000
Hello World! I have been seen 5 times.
[root@VM-8-10-centos composetest]# curl localhost:5000
Hello World! I have been seen 6 times.
[root@VM-8-10-centos composetest]# curl localhost:5000
Hello World! I have been seen 7 times.
Copy the code
conclusion
- Prepare the app app.py
- Dockerfile applications are packaged as images
- Docker-compose YAMl defines the entire service, required for the environment
- Start the Compose project
docker-compose up
process
- Create a network
- Perform Docker – compose – yml
- Start all services
$ ls
# Prepared documents
app.py docker-compose.yml Dockerfile requirements.txt
Copy the code
The rules
- Docker Images automatically downloads all dependent images
[root@VM-8-10-centos composetest]# docker imagesREPOSITORY TAG IMAGE ID CREATED SIZE composetest_Web latest e1a776378e7e 11 minutes ago 184MB Python 3.7-alpine A436fb2c575c 3 weeks ago 41.9MB Redis 5.0.9- AlPINE3.11 3661C84EE9d0 17 months ago 29.8MBCopy the code
- Docker Service is not currently in service
[root@VM-8-10-centos composetest]# docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
52a3bb4546dd redis:alpine "Docker - entrypoint. S..." 14 minutes ago Up 3 minutes 6379/tcp composetest_redis_1
480ad107851f composetest_web "flask run"14 minutes ago Up 3 minutes 0.0.0.0:5000->5000/ TCP, :::5000->5000/tcp composetest_web_1 [root@VM-8-10-centos composetest]# docker service ls #
Error response from daemon: This node is not a swarm manager. Use "docker swarm init" or "docker swarm join" to connect this node to swarm and try again.
Copy the code
Default service name filename _ service name _ _num, for example, composetest_web_1
_num indicates the number of replicas, which is used in cluster status
-
Network rules
$ docker network ls [root@VM-8-10-centos composetest]# docker network ls NETWORK ID NAME DRIVER SCOPE acaeca217cc5 bridge bridge local 152181e8650e composetest_default bridge local 3edbb9cd9ab0 host host local dad0ff6720e0 none null local Copy the code
Automatically creates a network composetest_default for us
The content in the project is all under the same network, and they can all be accessed by domain name
mysql:3360
Viewing Network Details
$ docker network inspect composetest_default "Containers": { "480ad107851fc859c79497f95999b917fbfd75e28ec8994f019a740f74798580": { "Name": "composetest_web_1"."EndpointID": "48252e19ea813a665fdbac7ff456bf893350e5f48b2452de7d3c2b4fe8f867ae"."MacAddress": "02:42:ac:13:00:02"."IPv4Address": "172.19.0.2/16"."IPv6Address": "" }, "52a3bb4546dd6526ff7e0fe11e2c0b33bd1efa8516da353845f84520d45e355f": { "Name": "composetest_redis_1"."EndpointID": "15ddf67cbbdbbad1fc922142a66ef9dfb302ed8a4ba65ad2d8b068228d512015"."MacAddress": "02:42:ac:13:00:03"."IPv4Address": "172.19.0.3/16"."IPv6Address": ""}},Copy the code
If we are in the same network, we can directly access through the domain name. Ensure high availability.
stop
Enter the project file
$ docker-compose down Use Ctrl+ C for default startup without -d
Copy the code
Docker-compose can now write a yamL configuration file for docker-compose up, which can start and stop all services in one click
conclusion
- Docker image. The Run = > container
- DockerFile build image => Service package
- Docker-compose startup project => Orchestrate multiple microservices/environments
- Docker network