IT策士 10余年一线大厂经验,专注 IT 思维、架构、职场进阶。我会在各个平台持续发布最新文章,助你少走弯路。
在上一篇文章的末尾,我留了一个问题:每次启动 Flask + Redis 应用都要敲七八条命令,太累了。有没有更优雅的方式?
有。这就是我们今天的主角------Docker Compose。
如果你跟着第 10 篇亲手敲过那几十条命令,一定能感受到手动管理的痛苦:要先创建网络、创建数据卷、启动 Redis、等待 Redis 就绪、启动 Flask......顺序不能错,参数不能漏,换一台机器又得重来一遍。Docker Compose 的目标就是把这些步骤写进一个 YAML 文件,然后一条命令搞定一切 。这篇就来带你入门 Compose,把 Flask + Redis 计数器应用的启动过程从"手动敲 8 条命令"变成"一条 docker compose up"。
一、Compose 是什么?解决什么问题?
Docker Compose 是 Docker 官方推出的多容器应用编排工具,核心价值就是用声明式的 YAML 文件描述整个应用栈,包括服务、网络、数据卷的配置,然后通过一条命令统一管理所有服务的生命周期。
看一下我们第 10 篇手动操作的痛点,以及 Compose 是如何一一解决的:
二、V1 vs V2 vs V3:我该用哪个?
在开始写配置文件之前,有必要弄清楚版本号的问题。
Docker Compose 文件格式经历了多次演变:V1 格式(docker-compose.yml,无 version 字段)是早期版本,已经彻底废弃;V2 格式引入了 version: '2.x',支持命名卷和网络;V3 格式(version: '3.x')增加了 Swarm 部署相关配置。
但现在(2024 年起)Docker 官方已弃用 version 字段。使用 docker compose(V2 命令,中间是空格,不是横杠)时,直接编写不带 version 的 YAML 文件即可,Docker 会自动使用 Compose Specification 规范解析。如果你看到一些教程还在使用 version: '3',那是历史遗留写法,功能上仍然可用,但官方推荐不再写 version。
本系列全部采用最新的 Compose Specification 格式(无 version 字段),命令使用 docker compose(空格版)。
三、编写第一个 docker-compose.yml
把第 10 篇的启动流程"翻译"成 Compose 文件。在项目根目录下新建 docker-compose.yml:
bash
# ============================================================
# Flask + Redis 计数器应用 ------ Docker Compose 配置文件
# 系列贯穿案例
# ============================================================
services:
# ---- Redis 服务 ----
redis:
image: redis:alpine
container_name: redis
restart: unless-stopped
command: redis-server --appendonly yes
volumes:
- redis-data:/data
networks:
- app-net
healthcheck:
test: ["CMD", "redis-cli", "ping"]
interval: 10s
timeout: 3s
retries: 3
start_period: 5s
# ---- Flask 应用服务 ----
flask-app:
image: flask-redis-counter:2.0
# 如果镜像不在本地,可以改为 build: . 来从 Dockerfile 构建
container_name: flask-app
restart: unless-stopped
ports:
- "5000:5000"
volumes:
- flask-logs:/app/logs
networks:
- app-net
depends_on:
redis:
condition: service_healthy
healthcheck:
test: ["CMD", "curl", "-f", "http://localhost:5000/health"]
interval: 30s
timeout: 3s
start_period: 5s
retries: 3
# ---- 数据卷 ----
volumes:
redis-data:
flask-logs:
# ---- 网络 ----
networks:
app-net:
driver: bridge
3.1 文件结构拆解
Compose 文件包含三个顶级元素:
services :定义应用栈中每个服务的配置。每个服务相当于一个 docker run 命令的完整参数集合。当前定义了两个服务------redis 和 flask-app。在 Compose 管理的网络中,服务名(redis、flask-app)会自动作为 DNS 记录,其他服务可以通过服务名直接访问。这就是为什么 app.py 里写的 host='redis' 能直接工作------Compose 自动创建了 DNS 解析。
volumes :声明命名卷。与手动执行 docker volume create 创建的效果完全一致,但由 Compose 统一管理生命周期。docker compose down 时默认不会删除 volumes(防止误删数据),如需删除需加 -v 参数。
networks :声明网络。driver: bridge 表示创建自定义 bridge 网络,与第 8 篇手动执行 docker network create app-net 的效果完全一致。
3.2 关键指令说明
3.3 depends_on 的两种写法
depends_on 有两种用法,效果差异很大:
简单写法(仅控制启动顺序):
这种写法只保证 redis 容器先启动,但不等待 Redis 服务就绪------redis 容器可能处于 "Up" 状态但 Redis 进程还在加载数据,此时 Flask 连接 Redis 会失败。
条件写法(等待健康检查通过):
bash
depends_on:
redis:
condition: service_healthy
这是我们现在用的写法:condition: service_healthy 表示不仅要等 redis 容器启动,还要等它的健康检查通过 (redis-cli ping 返回 PONG),才会启动 flask-app。这个 service_healthy 条件引入了 Compose v2.1+ 规范,到 Compose v3 曾被标记为 deprecated,但在最新的 Compose Specification 中又正式回归。使用 docker compose 命令即可正常使用,完全不需要 version 字段。
四、核心命令:从 up 到 down
4.1 docker compose up:一键启动
bash
# 前台启动(可以看到所有服务的日志交错输出)
docker compose up
# 后台启动(推荐日常使用)
docker compose up -d
输出:
bash
[+] Running 3/3
✔ Network flask-redis-counter_app-net Created 0.1s
✔ Volume "flask-redis-counter_redis-data" Created 0.0s
✔ Volume "flask-redis-counter_flask-logs" Created 0.0s
✔ Container redis Started 0.5s
✔ Container flask-app Started 1.2s
注意两个细节:第一,网络和卷的名称会自动带上项目名(默认是当前目录名,这里是 flask-redis-counter)作为前缀,避免不同项目之间的资源名称冲突。第二,docker compose up -d 仅启动服务,不会重新构建镜像。如果你修改了 Dockerfile 或代码,需要先 docker compose build 再 up,或者直接用 docker compose up --build -d。
4.2 查看服务状态
输出:
bash
NAME IMAGE COMMAND SERVICE STATUS PORTS
flask-app flask-redis-counter:2.0 "python app.py" flask-app running (healthy) 0.0.0.0:5000->5000/tcp
redis redis:alpine "docker-entrypoint.s..." redis running (healthy) 6379/tcp
注意两点:docker compose ps 只会显示当前项目 的容器(根据 docker-compose.yml 所在目录识别项目),不会混入宿主机上其他 Docker 容器;STATUS 列标注了 (healthy),说明两个服务的 HEALTHCHECK 都已通过。
4.3 查看日志
bash
# 查看所有服务的日志
docker compose logs
# 实时跟踪日志
docker compose logs -f
# 只看特定服务
docker compose logs flask-app
# 看最后 50 行
docker compose logs --tail=50 flask-app
docker compose logs 和 docker logs 最大的区别在于:前者会聚合所有服务的日志,并在每条日志前标注服务名,对于排查跨服务的调用链问题非常方便。
4.4 扩容服务
这是手动模式最难做到的事情------Compose 一条命令搞定:
bash
# 将 Flask 服务扩容到 3 个实例
docker compose up -d --scale flask-app=3
bash
[+] Running 3/3
✔ Container redis Running 0.0s
✔ Container flask-app Started 0.3s
✔ Container flask-app-2 Started 0.4s
✔ Container flask-app-3 Started 0.4s
--scale 参数在 docker compose 中仅用于临时一次性扩容 ,不会持久化到配置文件。下次执行 docker compose up -d 时,副本数会恢复为默认的 1 个。如果需要长期使用多个副本,建议在 Compose 文件中使用 deploy.replicas(需 Swarm 模式),或直接用 K8s 的 Deployment 管理。
4.5 停止与清理
bash
# 停止所有服务(不删除容器、网络、卷)
docker compose stop
# 启动已停止的服务
docker compose start
# 停止并删除容器(不删除网络和卷)
docker compose down
# 停止并删除容器、网络(保留卷,防止误删数据)
docker compose down --volumes
# 或简写
docker compose down -v
注意 :docker compose down 默认不会删除 volumes ,这是出于数据安全的考虑。如果你确定要彻底清理包括数据在内的所有资源,必须显式加 -v。
五、完整验证流程
bash
# 1. 确认目录结构
ls
# app.py docker-compose.yml Dockerfile requirements.txt .dockerignore
# 2. 启动应用栈
docker compose up -d
# 3. 查看状态
docker compose ps
# 4. 测试功能
curl http://localhost:5000
# Hello World! I have been seen 1 times.
curl http://localhost:5000
# Hello World! I have been seen 2 times.
# 5. 测试健康检查
curl http://localhost:5000/health
# {"status":"ok"}
# 6. 查看聚合日志
docker compose logs --tail=20
# 7. 停止服务
docker compose down
现在,整个 Flask + Redis 应用栈的启动从第 10 篇的"手动敲 8 条命令"变成了:
一条命令,从启动 Redis、等待就绪、启动 Flask,到创建网络和数据卷,全部自动完成。
六、V1 vs V2 命令对比
Docker Compose 有两个命令版本,如果你在网上看教程,可能会遇到混用的情况。以下是区别:
如果你之前用过
docker-compose(带横杠),现在统一换为docker compose(空格)。两者语法 99% 兼容,但 V2 在性能和功能上更优。
七、本篇总结
Docker Compose 解决的核心问题就是------把多容器应用从手动管理变成声明式管理。
-
声明式配置 :
docker-compose.yml一站式定义服务、网络、卷,可纳入 Git 管理 -
一键启停 :
docker compose up -d和docker compose down,告别冗长的手动命令 -
健康检查驱动的启动顺序 :
depends_on+condition: service_healthy,不再需要sleep -
服务扩容 :
--scale参数快速测试多副本场景 -
聚合日志:一个命令查看整个应用栈的日志,跨服务排错效率大幅提升
📝 本篇暂不要求实操 :你可以先阅读本文理解 Compose 的概念和基本命令。下一篇文章------第 12 篇:Docker Compose 文件详解:服务、网络与卷,我们将深入拆解 Compose 文件的每一个配置项,并带你亲手完成完整的部署演练。届时请务必跟着操作一遍。
想了解更多还可以去各个平台搜索「IT策士」,一起升级 IT 思维 !