Docker Compose 快速入门
本教程旨在通过引导您开发一个基础的 Python Web 应用程序,介绍 Docker Compose 的基本概念。
使用 Flask 框架,该应用在 Redis 中实现了访问计数器,提供了 Docker Compose 在 Web 开发场景中如何应用的实用示例。
即使您不熟悉 Python,这里演示的概念也应该易于理解。
这是一个非规范性示例,仅突出显示您可以使用 Compose 执行的关键操作。
前提条件
请确保您已具备:
- 已安装最新版本的 Docker Compose
- 对 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'在此示例中,
redis是应用网络上 Redis 容器的主机名,并使用默认端口6379。注意
请注意
get_hit_count函数的编写方式。这个基本的重试循环会在 Redis 服务不可用时多次尝试请求。这在应用启动上线时非常有用,同时也能在应用运行期间需要重启 Redis 服务时增强应用的韧性。在集群环境中,这也有助于处理节点间暂时的连接中断。在您的项目目录中创建另一个名为
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 及其他依赖项
- 复制
requirements.txt并安装 Python 依赖项。 - 向镜像添加元数据,以描述容器正在监听端口 5000。
- 将项目中的当前目录
.复制到镜像的工作目录.中。 - 将容器的默认命令设置为
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。
web 服务使用的是基于当前目录中的 Dockerfile 构建的镜像。
随后,它将容器与主机绑定到所暴露的端口 8000。此示例服务使用了 Flask Web 服务器的默认端口 5000。
redis 服务使用从 Docker Hub 注册表拉取的公共
Redis
镜像。
有关 compose.yaml 文件的更多信息,请参阅
Compose 的工作原理。
步骤 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 connectionsCompose 会拉取 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.yaml 文件,使用 watch,以便您可以预览正在运行的 Compose 服务;这些服务会在您编辑并保存代码时自动更新:
services:
web:
build: .
ports:
- "8000:5000"
develop:
watch:
- action: sync
path: .
target: /code
redis:
image: "redis:alpine"每当文件发生更改时,Compose 会将该文件同步到容器内 /code 下的对应位置。复制完成后,打包工具会在不重启的情况下更新正在运行的应用程序。
有关 Compose Watch 如何工作的更多信息,请参阅 使用 Compose Watch。或者,请参阅 管理容器中的数据以了解其他选项。
注意
为了使此示例正常工作,需将
--debug选项添加到Dockerfile。Flask 中的--debug选项可启用代码自动重载功能,从而无需重启或重建容器即可对后端 API 进行开发。 在修改.py文件后,后续的 API 调用将使用新代码,但在此小型示例中,浏览器界面不会自动刷新。大多数前端开发服务器均内置了原生实时重载支持,可与 Compose 协同工作。
步骤 5:使用 Compose 重新构建并运行应用
在您的项目目录中,输入 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 浏览器中检查 Hello World 消息,并刷新以查看计数增加。
步骤 6:更新应用程序
要查看 Compose Watch 的实际效果:
在
app.py中更改问候语并保存。例如,将Hello World!消息更改为Hello from Docker!:return f'Hello from Docker! I have been seen {count} times.\n'在浏览器中刷新应用。问候语应该会更新,计数器应继续递增。

完成后,运行
docker compose down。
第 7 步:拆分您的服务
使用多个 Compose 文件可以让您针对不同的环境或工作流自定义 Compose 应用。这对于大型应用非常有用,这类应用可能涉及数十个容器,且所有权分散在多个团队之间。
在您的项目文件夹中,创建一个名为
infra.yaml的新 Compose 文件。从您的
compose.yaml文件中剪切 Redis 服务,并将其粘贴到新的infra.yaml文件中。请确保在文件顶部添加services顶层属性。您的infra.yaml文件现在应如下所示:services: redis: image: "redis:alpine"在您的
compose.yaml文件中,添加include顶层属性以及指向infra.yaml文件的路径。include: - infra.yaml services: web: build: . ports: - "8000:5000" develop: watch: - action: sync path: . target: /code运行
docker compose up以使用更新后的 Compose 文件构建并启动应用。您应该在浏览器中看到Hello world消息。
这是一个简化的示例,但它演示了 include 的基本原理,以及它如何使将复杂应用模块化为多个子 Compose 文件变得更加容易。有关 include 和使用多个 Compose 文件的更多信息,请参阅
使用多个 Compose 文件。
第 8 步:尝试一些其他命令
如果您希望在后台运行服务,可以将
-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运行
docker compose --help以查看其他可用命令。如果您使用
docker compose up -d启动了 Compose,请在使用完服务后停止它们:$ docker compose stop您可以使用
docker compose down命令将所有内容停止并彻底移除容器。