前言
需要在宿主机启动较多容器时,如果每个模块都通过手动方式部署,效率非常低而且很容易出错。使用 Docker Compose 可以非常方便地定义和运行复杂应用,它是 Docker 提供的一个服务编排工具,Docker Compose 通过YML描述文件来完成对 Docker 容器的管理。
一、Docker Compose 简介
Docker Compose 是 Docker 官方的开源项目,托管于 github (GitHub - docker/compose)上,通过调用 Docker 服务的 API实现对 Docker 容器的快速编排,即通过一个单独的yml文件,来定义一组相关的容器来为一个项目服务。
>>> Docker Compose 的主要特性:
- 可以在单个主机上拥有多个隔离环境
Compose 使用项目名称来相互隔离环境。默认项目名称是项目目录的基本名称,可以使用 -p 参数或 COMPOSE_PROJECT_NAME 环境变量设置自定义项目名称。默认项目目录是 Compose 文件的基目录,可以使用命令行选项 --project-directory 定义它的自定义值。
- 创建容器时保留卷数据
Compose 会保留服务使用的所有卷,运行时 docker compose up ,如果它发现以前运行中的任何容器,则会将卷从旧容器复制到新容器。此过程可确保您在卷中创建的任何数据都不会丢失。
- 仅重新创建已更改的容器
Compose 缓存用于创建容器的配置,重新启动未更改的服务时,Compose 会重新使用现有容器。重复使用容器意味着可以非常快速地更改环境。
- 支持变量并在环境之间移动组合
Compose 支持 Compose 文件中的变量,Compose 在 shell 中查找环境变量并替换其值,如果未设置环境变量,Compose 将替换为空字符串。
>>> 使用 Docker Compose 三步走:
1、使用 Dockerfile 定义应用程序的环境,以便可以在任何地方复用。
2、在 docker-compose.yml 中定义组成应用程序的服务,以便它们可以在独立的环境中一起运行。
3、运行 docker compose up 命令启动并运行整个应用程序。
二、Docker Compose 安装
Docker Compose 依赖 Docker 的引擎来完成服务的编排,因此,在使用 Docker Compose 之前需要先安装好 Docker(Docker的安装)。Docker Compose v2 被规划为 Docker CLI 的一部分,安装好 Docker 后,可以直接使用。
###查看docker及docker compose版本。
root@docker:~# docker --version
Docker version 23.0.3, build 3e7cbfd
root@docker:~# docker compose version
Docker Compose version v2.17.2
也可以在 GitHub 上下载最新的二进制文件,GitHub 有时不太稳定,附一个 v2.19.0 版本64位 x86 Linux操作系统的 docker -compose 文件链接(docker-compose v2.19.0)。
###当前最新版本v2.19.0。
##设置目录变量,当前用户家目录下的.docker目录。
##如果选择给所有用户安装,而不只是当前用户,将文件下载到/usr/local/lib/docker/cli-plugins。
root@docker:~# DOCKER_CONFIG=${DOCKER_CONFIG:-$HOME/.docker}
##.docker目录下创建子目录cli-plugins。
root@docker:~# mkdir -p $DOCKER_CONFIG/cli-plugins
##下载二进制文件到cli-plugins目录。
root@docker:~# curl -SL https://github.com/docker/compose/releases/download/v2.19.0/docker-compose-`uname -s`-`uname -m` -o $DOCKER_CONFIG/cli-plugins/docker-compose
% Total % Received % Xferd Average Speed Time Time Time Current
Dload Upload Total Spent Left Speed
0 0 0 0 0 0 0 0 --:--:-- --:--:-- --:--:-- 0
100 57.6M 100 57.6M 0 0 374k 0 0:02:37 0:02:37 --:--:-- 281k
##给二进制文件增加可执行权限。
root@docker:~# chmod +x $DOCKER_CONFIG/cli-plugins/docker-compose
##查看docker compose版本。
root@docker:~# docker compose version
Docker Compose version v2.19.0
三、Compose 文件
Compose 文件是一个定义 Docker 应用程序的服务、网络和卷的 YAML 文件。
YAML 文件的语法特点:
- 大小写敏感
- 使用缩进表示层级关系
- 缩进不允许使用 tab,只允许空格
- 缩进的空格数不重要,只要相同层级的元素左对齐即可
- '#'表示注释
- 键值对用冒号来分隔
Compose 文件的默认是
compose.yaml 或 compose.yml,Compose 还向下兼容 docker-compose.yaml 和 docker-compose.yml,如果两个文件都存在,Compose 会优先选择规范的 compose.yaml 文件。
>>> Compose 文件格式版本:
Compose Specification 是 Compose 文件格式的最新推荐版本,Compose文件格式有三个旧版本,Version 1 已弃用,Version 2.x、Version 3.x 已合并到 Compose specification,并由 Docker Compose 1.27.0+ 实现。
Compose 和 Docker 兼容性矩阵:
Compose文件格式 Docker 版本 Compose specification 19.03.0+ 3.8 19.03.0+ 3.7 18.06.0+ 3.6 18.02.0+ 3.5 17.12.0+ 3.4 17.09.0+ 3.3 17.06.0+ 3.2 17.04.0+ 3.1 1.13.1+ 3.0 1.13.0+ 2.4 17.12.0+ 2.3 17.06.0+ 2.2 1.13.0+ 2.1 1.12.0+ 2.0 1.10.0+
>>> 常用配置参数:
- version
版本信息,Compose V2使用 Compose 规范进行项目定义,版本字段应省略,如果存在,则忽略该字段。
- name
定义项目名称。
- services
定义所有的服务信息,下一级紧跟的参数是服务的名字。
- build
build 指定用于从源创建容器镜像的生成配置。
- context 指定 Dockerfile 文件所在的路径。
- dockerfile 指定 Dockerfile 文件。
- args 定义构建镜像参数。
- image
指定镜像,如果本地没有,尝试从仓库拉取。
- command
覆盖容器启动后默认执行的命令。
- depends_on
定义容器依赖关系,即启动顺序。
- environment
设置环境变量。
- container_name
指定容器名字。
- hostname
指定容器主机名。
- extra_hosts
在构建时添加主机名映射,即容器的 hosts 文件。
- ports
建立宿主机和容器之间的端口映射关系,指定两个端口 (HOST:CONTAINER),或仅指定容器端口。在后一种情况下,Compose 会自动分配主机的任何未分配端口。
例:ports:
- "3000"
- "3000-3005"
- "8000:8000"
- "9090-9091:8080-8081"
- "49100:22"
- "8000-9000:80"
- "127.0.0.1:8001:8001"
- "127.0.0.1:5000-5010:5000-5010"
- "6060:6060/udp"
- restart
定义在容器终止时重启策略。
- no:默认重启策略。在任何情况下它都不会重新启动容器。
- always:该策略始终重新启动容器,直到将其删除。
- on-failure:如果退出代码指示错误,策略将重新启动容器。
- unless-stopped:无论退出代码如何,策略都会重新启动容器,但在服务停止或删除时停止重新启动。
- ulimits
指定容器的ulimit。
例:ulimits:
nproc: 65535
nofile:
soft: 20000
hard: 40000
- volumes
数据卷所挂载路径设置,可以设置宿主机路径 (HOST_PATH:CONTAINER_PATH) 或加上访问模式 (HOST_PATH:CONTAINER_PATH:ro)。
例:volumes:
- /data:/var/lib/mysql
- ~/configs:/etc/configs/:ro
- volumes_from
从其他服务或容器挂载数据卷。
- networks
定义容器网络。
- network_mode
定义网络模式。
- none:关闭所有容器网络。
- host:为容器提供对主机网络接口的原始访问权限。
- service:{name}:仅允许容器访问指定的服务。
四、Docker Compose 使用
1、常用命令
执行 docker compose help 命令可以查看帮助手册。
用法:docker compose [OPTIONS] COMMAND
OPTIONS:
- -f ,指定模板文件,即 compose 文件,可以多次指定。
- -p,指定项目名称,默认使用所在目录名作为项目名称。
COMMAND:
以下指令大多默认需要在 compose 文件所在目录下执行,如想在 compose 外的目录执行也可以通过 -f 参数或 COMPOSE_FILE 环境变量指定 compose 文件路径。
- build,构建项目中的镜像。
- config,验证 compose 文件格式。
- cp,在服务容器和本地文件系统之间复制文件/文件夹。
- up,启动或更新 compose 文件中定义的服务,一般配合 -d 参数使用,后台运行容器。
- down,停止并移除 up 命令启动的容器和网络。
- exec,在服务(容器)中执行命令。
- images,列出服务中创建容器使用的镜像。
- kill,通过发送信号,强制运行的容器停止。
- logs,查看服务容器的输出日志。
- ls,列出正在运行的 Compose 项目。
- pause,暂停服务。
- port ,打印出服务绑定的端口。
- ps,列出项目中的容器。
- pull,拉取服务使用的镜像。
- push,推送服务使用的镜像。
- restart,重新启动 compose 文件中定义的服务。
- rm,删除已停止的容器。
- run,对服务容器运行一次性命令。
- start,启动 compose 文件中定义的服务。
- stop,停止 compose 文件中定义的服务。
- top,查看各个容器中的进程。
- unpause,恢复处于暂停状态中的服务。
- version,查看 Docker Compose版本
2、Docker Compose 实例
2.1、定义程序依赖项
1)为项目创建一个目录,并进入到该目录中。
root@docker:/docker# mkdir composetest
root@docker:/docker# cd composetest/
root@docker:/docker/composetest#
2)在项目目录中创建一个名为 app.py 的文件,并编辑内容进去。
root@docker:/docker/composetest# vi 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)
3)在项目目录中创建一个名为 requirements.txt 的文件,并将以下代码编辑进去。
root@docker:/docker/composetest# vi requirements.txt
编辑入以下内容:
flask
redis
2.2、创建 Dockerfile
Dockerfile 用于构建 Docker 镜像。该映像包含 Python 应用程序所需的所有依赖项,包括 Python 本身。容器学习Day12-使用Dockerfile构建容器镜像_AtobeKegio的博客-CSDN博客
在项目目录中创建 Dockerfile 文件。
root@docker:/docker/composetest# vi Dockerfile
编辑入以下内容:
# syntax=docker/dockerfile:1
FROM python:3.7-alpine #从Python3.7镜像开始构建镜像。
WORKDIR /code #将工作目录设置为/code。
ENV FLASK_APP=app.py #设置命令使用的环境变量flask。
ENV FLASK_RUN_HOST=0.0.0.0 #设置命令使用的环境变量flask。
RUN apk add --no-cache gcc musl-dev linux-headers #安装gcc和其他依赖项。
COPY requirements.txt requirements.txt #复制requirements.txt。
RUN pip install -r requirements.txt #安装Python依赖项。
EXPOSE 5000 #向镜像添加元数据以描述容器正在侦听端口5000。
COPY . . #将项目中的当前目录复制到镜像中的workdir。
CMD ["flask", "run"] #将容器的默认命令设置为flask run。
2.3、构建 Compose 文件
在项目目录中创建一个名为 compose.yaml 的文件并粘编辑内容。
root@docker:/docker/composetest# vi compose.yaml
编辑入以下内容:
services:
web:
build: .
ports:
- "8000:5000"
redis:
image: "redis:alpine"
此 Compose 文件定义了两个服务:web 和 redis,该服务使用从当前目录中的 Dockerfile 构建镜像,Flask Web 服务的默认端口5000,将5000端口映射到宿主机的8000端口提供服务,redis镜像名 redis:alpine。
2.4、使用命令运行程序
1)在项目目录中运行 docker compose up -d 命令,启动应用程序。
root@docker:/docker/composetest# docker compose up -d
[+] Running 7/7
✔ redis 6 layers [⣿⣿⣿⣿⣿⣿] 0B/0B Pulled 4.9s
✔ 59bf1c3509f3 Pull complete 2.9s
✔ 719adce26c52 Pull complete 3.0s
✔ b8f35e378c31 Pull complete 3.2s
✔ d034517f789c Pull complete 3.8s
✔ 3772d4d76753 Pull complete 3.9s
✔ 211a7f52febb Pull complete 4.0s
[+] Building 244.9s (13/13) FINISHED
=> [web internal] load .dockerignore 0.0s
=> => transferring context: 2B 0.0s
=> [web internal] load build definition from Dockerfile 0.0s
=> => transferring dockerfile: 321B 0.0s
=> [web] resolve image config for docker.io/docker/dockerfile:1 15.3s
=> CACHED [web] docker-image://docker.io/docker/dockerfile:1@sha256:42399d4635eddd7a9b8a24be879d2f9a930d0ed040a61324cfdf59ef1357b3b2 0.0s
=> [web internal] load metadata for docker.io/library/python:3.7-alpine 16.3s
=> [web 1/6] FROM docker.io/library/python:3.7-alpine@sha256:d64e0124674d64e78cc9d7378a1130499ced66a7a00db0521d0120a2e88ac9e4 2.0s
=> => resolve docker.io/library/python:3.7-alpine@sha256:d64e0124674d64e78cc9d7378a1130499ced66a7a00db0521d0120a2e88ac9e4 0.0s
=> => sha256:a1034fd13493569ef2975c7c8c3bdd8aecee43aa2a9f102a24380b9cb724535b 8.10kB / 8.10kB 0.0s
=> => sha256:8786870f287676cca49c1e1e5029467c087ad293b824fcddc489cbe2819745b2 282.15kB / 282.15kB 0.5s
=> => sha256:45d4696938d0cf96f85ae2d9a8eb8c0bb018e07b0f2a820c3118a7cb54e4dad8 10.55MB / 10.55MB 1.2s
=> => sha256:ef84af58b2c5560afbdd9265a475c59fe10c72032153ab8a79e77b961985c580 230B / 230B 0.3s
=> => sha256:d64e0124674d64e78cc9d7378a1130499ced66a7a00db0521d0120a2e88ac9e4 1.65kB / 1.65kB 0.0s
=> => sha256:98bdc8dd3aa5157f990a13a9cb58d4f9b8d089ae825c0d85b9d68e0c5f1918bd 1.37kB / 1.37kB 0.0s
=> => sha256:c3c9b71b9a6957b500a5a45f5608c0099a8e7c9ba0714701cd041198d95b319b 2.35MB / 2.35MB 0.9s
=> => extracting sha256:8786870f287676cca49c1e1e5029467c087ad293b824fcddc489cbe2819745b2 0.1s
=> => extracting sha256:45d4696938d0cf96f85ae2d9a8eb8c0bb018e07b0f2a820c3118a7cb54e4dad8 0.4s
=> => extracting sha256:ef84af58b2c5560afbdd9265a475c59fe10c72032153ab8a79e77b961985c580 0.0s
=> => extracting sha256:c3c9b71b9a6957b500a5a45f5608c0099a8e7c9ba0714701cd041198d95b319b 0.2s
=> [web internal] load build context 0.0s
=> => transferring context: 1.11kB 0.0s
=> [web 2/6] WORKDIR /code 0.1s
=> [web 3/6] RUN apk add --no-cache gcc musl-dev linux-headers 198.4s
=> [web 4/6] COPY requirements.txt requirements.txt 0.0s
=> [web 5/6] RUN pip install -r requirements.txt 11.9s
=> [web 6/6] COPY . . 0.0s
=> [web] exporting to image 0.8s
=> => exporting layers 0.8s
=> => writing image sha256:3dd95b488d491dba06a0b364be1b535c123b031055f710a30cee2103b0b78c64 0.0s
=> => naming to docker.io/library/composetest-web 0.0s
[+] Running 3/3
✔ Network composetest_default Created 0.1s
✔ Container composetest-redis-1 Started 0.8s
✔ Container composetest-web-1 Started
2)访问应用服务测试,每次访问显示次数会增加,也可以浏览器访问测试。
root@docker:/docker/composetest# curl http://127.0.0.1:8000
Hello World! I have been seen 1 times.
root@docker:/docker/composetest# curl http://127.0.0.1:8000
Hello World! I have been seen 2 times.
3) 停止应用程序。
root@docker:/docker/composetest# docker compose down
[+] Running 3/3
✔ Container composetest-web-1 Removed 10.3s
✔ Container composetest-redis-1 Removed 0.2s
✔ Network composetest_default Removed
2.5、编辑 Compose 文件添加数据卷绑定
参数 volumes 将主机上的项目目录(当前目录)挂载到 /code 容器内部,允许动态修改代码,而无需重建镜像,即持久化存储文件。environment 参数设置 FLASK_DEBUG 环境变量,它告诉 flask run 在开发模式下运行并在更改时重新加载代码。
vi compose.yaml
编辑前文件内容:
services:
web:
build: .
ports:
- "8000:5000"
redis:
image: "redis:alpine"
编辑后文件内容:
services:
web:
build: .
ports:
- "8000:5000"
volumes:
- .:/code
environment:
FLASK_DEBUG: "true"
redis:
image: "redis:alpine"
2.6、使用 Compose 重新构建并运行应用程序
root@docker:/docker/composetest# docker compose up -d
[+] Running 3/3
✔ Network composetest_default Created 0.1s
✔ Container composetest-web-1 Started 1.0s
✔ Container composetest-redis-1 Started 1.0s
root@docker:/docker/composetest# curl http://127.0.0.1:8000
Hello World! I have been seen 1 times.
2.7、 更新应用程序
由于应用程序代码使用卷挂载到容器中,可以更改其代码并立即查看更改,而不需要重建镜像。修改 app.py 文件,将最后一句中 "Hello World" 替换为 "Hello from Docker",查看效果。
root@docker:/docker/composetest# vi app.py
编辑前内容:
return 'Hello World! I have been seen {} times.\n'.format(count)
编辑后内容:
return 'Hello from Docker! I have been seen {} times.\n'.format(count)
#访问测试,发现内容已变。
root@docker:/docker/composetest# curl http://127.0.0.1:8000
Hello from Docker! I have been seen 2 times.
总结
以上就是今天要讲的内容,介绍了 Docker Compose 的使用。