Docker Compose 入门:一键编排 Flask + Redis 多容器应用
上一篇我们用 Docker 把一个 Flask 应用打成了镜像并跑了起来,但真实项目很少只有一个容器:Web 应用背后通常还站着数据库、缓存、消息队列。如果继续手动逐个 docker run,再想办法让它们互相找到对方,既繁琐又容易出错。Docker Compose 就是解决这个问题的工具:用一个 YAML 文件描述所有服务,一条命令完成整组容器的启动和销毁。
一、Docker Compose 是什么
Docker Compose 是官方的多容器编排工具。你把每个容器的镜像、端口、环境变量、依赖关系写进一个 docker-compose.yml,之后:
docker compose up一条命令创建并启动全部服务;docker compose down一条命令停止并清理全部服务。
从 Docker 20.x 之后,Compose V2 已作为插件内置在 Docker CLI 中,命令写作 docker compose(空格),可以直接用 docker compose version 验证是否可用。
二、改造应用:接入 Redis 访问计数
沿用上次的 Flask 项目结构,这次加一个 Redis 做访问计数。先更新 requirements.txt:
flask==3.0.3
redis==5.0.4
改写 app.py:
from flask import Flask
import redis
import socket
import os
app = Flask(__name__)
cache = redis.Redis(
host=os.environ.get("REDIS_HOST", "localhost"),
port=6379,
decode_responses=True
)
@app.route("/")
def index():
count = cache.incr("visits")
return f"Hello from {socket.gethostname()}! 本页已被访问 {count} 次。"
if __name__ == "__main__":
app.run(host="0.0.0.0", port=5000)
两处值得注意的写法:
- Redis 地址从环境变量
REDIS_HOST读取,而不是写死——这正是为编排做的准备,容器里 localhost 指向容器自身,永远连不到 Redis 容器; INCR是 Redis 的原子自增命令,多个请求并发计数也不会丢数。
Dockerfile 和上一篇完全一样,无需改动:
FROM python:3.12-slim
WORKDIR /app
COPY requirements.txt .
RUN pip install --no-cache-dir -r requirements.txt -i https://mirrors.huaweicloud.com/repository/pypi/simple
COPY app.py .
EXPOSE 5000
CMD ["python", "app.py"]
三、编写 docker-compose.yml
在项目根目录创建 docker-compose.yml:
services:
web:
build: .
ports:
- "8000:5000"
environment:
- REDIS_HOST=redis
depends_on:
- redis
redis:
image: redis:7-alpine
volumes:
- redis-data:/data
volumes:
redis-data:
逐项说明:
build: .:这个服务用当前目录的 Dockerfile 构建,也就是我们的 Flask 应用;ports:端口映射,与docker run -p等价;environment:注入环境变量,把REDIS_HOST指向redis;depends_on:声明启动顺序,Compose 会先创建 redis 再创建 web;image: redis:7-alpine:Redis 直接用官方镜像,体积小;volumes:定义命名卷把 Redis 数据落在宿主机,容器重建后计数不丢。
关键一点:在 Compose 创建的网络里,服务名就是主机名。所以 REDIS_HOST=redis 能直接连通,不需要知道容器 IP。
四、一条命令启动整组服务
构建并后台启动:
docker compose up -d
查看状态和日志:
docker compose ps
docker compose logs -f web
验证效果:
curl http://127.0.0.1:8000/
# Hello from <容器ID>! 本页已被访问 1 次。
curl http://127.0.0.1:8000/
# Hello from <容器ID>! 本页已被访问 2 次。
多次刷新,计数持续增长,说明 Flask 与 Redis 在两个容器之间已经正常通信。用完之后一条命令清理:
docker compose down
加上 -v 参数(docker compose down -v)可以连同数据卷一起删除。
五、几个常见的坑
- depends_on 不等于"就绪":它只保证启动顺序,不保证服务可用。Redis 几乎瞬间就绪所以感觉不到,换成 MySQL 就经常遇到 Web 启动时连不上库,要么在应用里做连接重试,要么给依赖服务配置 healthcheck;
- 容器之间不要用 localhost 互连:localhost 是容器自己,要用服务名;
- YAML 缩进错误:缩进必须用空格,不能用 Tab,层级写错是最常见的启动失败原因;
- 改了 Dockerfile 或依赖后:需要
docker compose up -d --build才会重新构建镜像,否则跑的还是旧镜像。
六、小结
从单容器到多容器,Docker Compose 把"环境"沉淀成了一份可版本管理的 YAML 文件,团队里任何人 clone 下代码,一条 docker compose up 就能在本地复现整套环境,这也是它成为本地开发标配的原因。下一步可以把镜像推送到华为云 SWR,再接入 CCE 等容器服务走向生产环境。两篇文章连起来,单容器和多容器的入门实践就都齐了。
- 点赞
- 收藏
- 关注作者
评论(0)