
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 composeV2 命令中间是空格不是横杠时直接编写不带version的 YAML 文件即可Docker 会自动使用 Compose Specification 规范解析。如果你看到一些教程还在使用version: 3那是历史遗留写法功能上仍然可用但官方推荐不再写version。本系列全部采用最新的 Compose Specification 格式无 version 字段命令使用docker compose空格版。三、编写第一个 docker-compose.yml把第 10 篇的启动流程翻译成 Compose 文件。在项目根目录下新建docker-compose.yml# # Flask Redis 计数器应用 —— Docker Compose 配置文件# 系列贯穿案例# services:# ---- Redis 服务 ----redis: image: redis:alpine container_name: redis restart: unless-stopped command: redis-server--appendonlyyesvolumes: - redis-data:/data networks: - app-net healthcheck: test:[CMD,redis-cli,ping]interval: 10s timeout: 3s retries:3start_period: 5s# ---- Flask 应用服务 ----flask-app: image: flask-redis-counter:2.0# 如果镜像不在本地可以改为 build: . 来从 Dockerfile 构建container_name: flask-app restart: unless-stopped ports: -5000:5000volumes: - 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: bridge3.1 文件结构拆解Compose 文件包含三个顶级元素services定义应用栈中每个服务的配置。每个服务相当于一个docker run命令的完整参数集合。当前定义了两个服务——redis和flask-app。在 Compose 管理的网络中服务名redis、flask-app会自动作为 DNS 记录其他服务可以通过服务名直接访问。这就是为什么app.py里写的hostredis能直接工作——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 会失败。条件写法等待健康检查通过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 到 down4.1 docker compose up一键启动# 前台启动可以看到所有服务的日志交错输出dockercompose up# 后台启动推荐日常使用dockercompose up-d输出[]Running3/3 ✔ Network flask-redis-counter_app-net Created0.1s ✔ Volumeflask-redis-counter_redis-dataCreated0.0s ✔ Volumeflask-redis-counter_flask-logsCreated0.0s ✔ Container redis Started0.5s ✔ Container flask-app Started1.2s注意两个细节第一网络和卷的名称会自动带上项目名默认是当前目录名这里是flask-redis-counter作为前缀避免不同项目之间的资源名称冲突。第二docker compose up -d仅启动服务不会重新构建镜像。如果你修改了 Dockerfile 或代码需要先docker compose build再up或者直接用docker compose up --build -d。4.2 查看服务状态输出NAME IMAGE COMMAND SERVICE STATUS PORTS flask-app flask-redis-counter:2.0python app.pyflask-app running(healthy)0.0.0.0:5000-5000/tcp redis redis:alpinedocker-entrypoint.s…redis running(healthy)6379/tcp注意两点docker compose ps只会显示当前项目的容器根据docker-compose.yml所在目录识别项目不会混入宿主机上其他 Docker 容器STATUS 列标注了(healthy)说明两个服务的 HEALTHCHECK 都已通过。4.3 查看日志# 查看所有服务的日志dockercompose logs# 实时跟踪日志dockercompose logs-f# 只看特定服务dockercompose logs flask-app# 看最后 50 行dockercompose logs--tail50flask-appdocker compose logs和docker logs最大的区别在于前者会聚合所有服务的日志并在每条日志前标注服务名对于排查跨服务的调用链问题非常方便。4.4 扩容服务这是手动模式最难做到的事情——Compose 一条命令搞定# 将 Flask 服务扩容到 3 个实例dockercompose up-d--scaleflask-app3[]Running3/3 ✔ Container redis Running0.0s ✔ Container flask-app Started0.3s ✔ Container flask-app-2 Started0.4s ✔ Container flask-app-3 Started0.4s--scale参数在 docker compose 中仅用于临时一次性扩容不会持久化到配置文件。下次执行docker compose up -d时副本数会恢复为默认的 1 个。如果需要长期使用多个副本建议在 Compose 文件中使用deploy.replicas需 Swarm 模式或直接用 K8s 的 Deployment 管理。4.5 停止与清理# 停止所有服务不删除容器、网络、卷dockercompose stop# 启动已停止的服务dockercompose start# 停止并删除容器不删除网络和卷dockercompose down# 停止并删除容器、网络保留卷防止误删数据dockercompose down--volumes# 或简写dockercompose down-v注意docker compose down默认不会删除 volumes这是出于数据安全的考虑。如果你确定要彻底清理包括数据在内的所有资源必须显式加-v。五、完整验证流程# 1. 确认目录结构ls# app.py docker-compose.yml Dockerfile requirements.txt .dockerignore# 2. 启动应用栈dockercompose up-d# 3. 查看状态dockercomposeps# 4. 测试功能curlhttp://localhost:5000# Hello World! I have been seen 1 times.curlhttp://localhost:5000# Hello World! I have been seen 2 times.# 5. 测试健康检查curlhttp://localhost:5000/health# {status:ok}# 6. 查看聚合日志dockercompose logs--tail20# 7. 停止服务dockercompose 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_oncondition: service_healthy不再需要sleep服务扩容--scale参数快速测试多副本场景聚合日志一个命令查看整个应用栈的日志跨服务排错效率大幅提升 本篇暂不要求实操你可以先阅读本文理解 Compose 的概念和基本命令。下一篇文章——第 12 篇Docker Compose 文件详解服务、网络与卷我们将深入拆解 Compose 文件的每一个配置项并带你亲手完成完整的部署演练。届时请务必跟着操作一遍。想了解更多还可以去各个平台搜索「IT策士」一起升级 IT 思维