Docker Compose 快速入门
本教程旨在通过指导您开发基本的 Python Web 应用程序来介绍 Docker Compose 的基本概念。
使用 Flask 框架,该应用程序在 Redis 中具有命中计数器,提供了如何在 Web 开发场景中应用 Docker Compose 的实际示例。
即使您不熟悉 Python,此处演示的概念也应该是可以理解的。
这是一个非规范性示例,它只强调了您可以使用 Compose 执行的关键操作。
先决条件
确保您拥有:
- 已安装最新版本的 Docker Compose
- 基本了解 Docker 概念和 Docker 的工作原理
第 1 步:设置
为项目创建一个目录:
$ mkdir composetest $ cd composetest
在项目目录中创建一个名为 的文件,并将以下代码粘贴到其中:
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 f'Hello World! I have been seen {count} times.\n'
在此示例中,是 应用程序的 network 和 default 端口。
redis
6379
注意
请注意函数的编写方式。此基本重试 如果 Redis 服务为 不可用。这在应用程序启动时很有用 联机,但如果 Redis 服务需要在应用程序的生命周期内随时重新启动。在 cluster 的 API API 中,这也有助于处理 节点。
get_hit_count
创建另一个名为 project 目录中的文件,然后 将以下代码粘贴到:
requirements.txt
flask redis
创建一个并粘贴以下代码:
Dockerfile
# syntax=docker/dockerfile:1 FROM python:3.10-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", "--debug"]
这会告诉 Docker :
- 从 Python 3.10 镜像开始构建镜像。
- 将工作目录设置为 .
/code
- 设置命令使用的环境变量。
flask
- 安装 gcc 和其他依赖项
- 复制并安装 Python 依赖项。
requirements.txt
- 将元数据添加到镜像中,以描述容器正在侦听端口 5000
- 将项目中的当前目录复制到镜像中的 workdir。
.
.
- 将容器的默认命令设置为 。
flask run --debug
重要
检查 没有像 .某些编辑器可能会自动附加此文件扩展名,这会导致您在运行应用程序时出现错误。
Dockerfile
.txt
有关如何编写 Dockerfile 的更多信息,请参阅 Dockerfile 参考。
第 2 步:在 Compose 文件中定义服务
Compose 简化了对整个应用程序堆栈的控制,从而可以轻松地在单个易于理解的 YAML 配置文件中管理服务、网络和卷。
在项目目录中创建一个名为 的文件,并将
以下内容:compose.yaml
services:
web:
build: .
ports:
- "8000:5000"
redis:
image: "redis:alpine"
此 Compose 文件定义了两个服务:和 .web
redis
该服务使用从当前目录中构建的镜像。
然后,它将容器和主机绑定到公开的端口 .此示例服务使用 Flask Web 服务器的默认端口。web
Dockerfile
8000
5000
该服务使用从 Docker Hub 注册表中提取的公有 Redis 镜像。redis
有关该文件的更多信息,请参阅 Compose 的工作原理。compose.yaml
第 3 步:使用 Compose 构建并运行应用
只需一个命令,您就可以从配置文件中创建和启动所有服务。
在项目目录中,通过运行 .
docker compose up
$ docker compose up Creating network "composetest_default" with the default driver Creating composetest_web_1 ... Creating composetest_redis_1 ... Creating composetest_web_1 Creating composetest_redis_1 ... done Attaching to composetest_web_1, composetest_redis_1 web_1 | * Running on http://0.0.0.0:5000/ (Press CTRL+C to quit) redis_1 | 1:C 17 Aug 22:11:10.480 # oO0OoO0OoO0Oo Redis is starting oO0OoO0OoO0Oo redis_1 | 1:C 17 Aug 22:11:10.480 # Redis version=4.0.1, bits=64, commit=00000000, modified=0, pid=1, just started redis_1 | 1:C 17 Aug 22:11:10.480 # Warning: no config file specified, using the default config. In order to specify a config file use redis-server /path/to/redis.conf web_1 | * Restarting with stat redis_1 | 1:M 17 Aug 22:11:10.483 * Running mode=standalone, port=6379. redis_1 | 1:M 17 Aug 22:11:10.483 # WARNING: The TCP backlog setting of 511 cannot be enforced because /proc/sys/net/core/somaxconn is set to the lower value of 128. web_1 | * Debugger is active! redis_1 | 1:M 17 Aug 22:11:10.483 # Server initialized redis_1 | 1:M 17 Aug 22:11:10.483 # WARNING you have Transparent Huge Pages (THP) support enabled in your kernel. This will create latency and memory usage issues with Redis. To fix this issue run the command 'echo never > /sys/kernel/mm/transparent_hugepage/enabled' as root, and add it to your /etc/rc.local in order to retain the setting after a reboot. Redis must be restarted after THP is disabled. web_1 | * Debugger PIN: 330-787-903 redis_1 | 1:M 17 Aug 22:11:10.483 * Ready to accept connections
Compose 会拉取一个 Redis 镜像,为您的代码构建一个镜像,然后启动 您定义的服务。在这种情况下,代码将在构建时静态复制到镜像中。
在浏览器中输入 以查看应用程序正在运行。
http://localhost:8000/
如果这没有解决,您也可以尝试 。
http://127.0.0.1:8000
您应该在浏览器中看到一条消息,内容为:
Hello World! I have been seen 1 times.
刷新页面。
该数字应递增。
Hello World! I have been seen 2 times.
切换到另一个终端窗口,然后键入以列出本地镜像。
docker image ls
此时列出镜像应返回 和 。
redis
web
$ docker image ls REPOSITORY TAG IMAGE ID CREATED SIZE composetest_web latest e2c21aa48cc1 4 minutes ago 93.8MB python 3.4-alpine 84e6077c7ab6 7 days ago 82.5MB redis alpine 9d8fa9aa0e5b 3 weeks ago 27.5MB
您可以使用 检查镜像。
docker inspect <tag or id>
通过从第二个终端中的项目目录中运行,或通过 点击您启动应用程序的原始终端。
docker compose down
CTRL+C
第 4 步:编辑 Compose 文件以使用 Compose Watch
编辑项目目录中要使用的文件,以便您可以预览正在运行的 Compose 服务,这些服务会在您编辑和保存代码时自动更新:compose.yaml
watch
services:
web:
build: .
ports:
- "8000:5000"
develop:
watch:
- action: sync
path: .
target: /code
redis:
image: "redis:alpine"
每当文件发生更改时,Compose 都会将文件同步到容器内的相应位置。复制后,打包程序会更新正在运行的应用程序,而无需重新启动。/code
如需详细了解 Compose Watch 的工作原理,请参阅使用 Compose Watch。或者,有关其他选项,请参阅管理容器中的数据。
注意
要使此示例正常工作,请将该选项添加到 .Flask 中的选项支持自动代码重新加载,从而可以在后端 API 上工作,而无需重新启动或重新构建容器。 更改文件后,后续 API 调用将使用新代码,但在此小示例中,浏览器 UI 不会自动刷新。大多数前端开发服务器都包含可与 Compose 配合使用的原生实时重新加载支持。
--debug
Dockerfile
--debug
.py
第 5 步:使用 Compose 重新构建并运行应用
在项目目录中,键入 or 以构建并启动应用程序,然后启动文件监视模式。docker compose watch
docker compose up --watch
$ docker compose watch
[+] Running 2/2
✔ Container docs-redis-1 Created 0.0s
✔ Container docs-web-1 Recreated 0.1s
Attaching to redis-1, web-1
⦿ watch enabled
...
再次在 Web 浏览器中检查该消息,然后刷新以查看
count 增量。Hello World
第 6 步:更新应用程序
要查看 Compose Watch 的实际应用,请执行以下操作:
更改问候语并保存。例如,将消息更改为 :
app.py
Hello World!
Hello from Docker!
return f'Hello from Docker! I have been seen {count} times.\n'
在浏览器中刷新应用程序。问候语应更新,并且 counter 应仍为递增。
完成后,运行 .
docker compose down
第 7 步:拆分您的服务
使用多个 Compose 文件,您可以针对不同的环境或工作流程自定义 Compose 应用程序。这对于可能使用数十个容器且所有权分布在多个团队中的大型应用程序非常有用。
在项目文件夹中,创建一个名为 的新 Compose 文件。
infra.yaml
从您的文件中剪切 Redis 服务并将其粘贴到新文件中。确保在文件顶部添加 top-level 属性。您的文件现在应如下所示:
compose.yaml
infra.yaml
services
infra.yaml
services: redis: image: "redis:alpine"
在您的文件中,添加 top-level 属性以及文件的路径。
compose.yaml
include
infra.yaml
include: - infra.yaml services: web: build: . ports: - "8000:5000" develop: watch: - action: sync path: . target: /code
Run 以使用更新的 Compose 文件构建应用程序,然后运行它。您应该会在浏览器中看到该消息。
docker compose up
Hello world
这是一个简化的示例,但它演示了将复杂应用程序模块化为子 Compose 文件的基本原理以及如何更轻松地将其模块化。有关和处理多个 Compose 文件的更多信息,请参阅使用多个 Compose 文件。include
include
第 8 步:尝试使用其他一些命令
如果你想在后台运行你的服务,你可以将标志(用于 “detached” 模式)传递给 for view 当前正在运行的内容:
-d
docker compose up
docker compose ps
$ docker compose up -d Starting composetest_redis_1... Starting composetest_web_1... $ docker compose ps Name Command State Ports ------------------------------------------------------------------------------------- composetest_redis_1 docker-entrypoint.sh redis ... Up 6379/tcp composetest_web_1 flask run Up 0.0.0.0:8000->5000/tcp
Run 可查看其他可用命令。
docker compose --help
如果您使用 启动 Compose,请在使用完服务后停止服务:
docker compose up -d
$ docker compose stop
您可以使用命令关闭所有内容,完全删除容器。
docker compose down