Docker Compose 入门:一键编排 Flask + Redis 多容器应用

举报
yd_243549746 发表于 2026/10/25 15:01:42 2026/10/25
【摘要】 本文是 Docker 入门系列第二篇:在上篇单容器 Flask 实践的基础上,接入 Redis 实现访问计数,通过编写 docker-compose.yml 一条命令编排多容器应用,并整理了 depends_on 与就绪状态、容器互联、YAML 缩进等常见坑的处理方法。

上一篇我们用 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)可以连同数据卷一起删除。

五、几个常见的坑

  1. depends_on 不等于"就绪":它只保证启动顺序,不保证服务可用。Redis 几乎瞬间就绪所以感觉不到,换成 MySQL 就经常遇到 Web 启动时连不上库,要么在应用里做连接重试,要么给依赖服务配置 healthcheck;
  2. 容器之间不要用 localhost 互连:localhost 是容器自己,要用服务名;
  3. YAML 缩进错误:缩进必须用空格,不能用 Tab,层级写错是最常见的启动失败原因;
  4. 改了 Dockerfile 或依赖后:需要 docker compose up -d --build 才会重新构建镜像,否则跑的还是旧镜像。

六、小结

从单容器到多容器,Docker Compose 把"环境"沉淀成了一份可版本管理的 YAML 文件,团队里任何人 clone 下代码,一条 docker compose up 就能在本地复现整套环境,这也是它成为本地开发标配的原因。下一步可以把镜像推送到华为云 SWR,再接入 CCE 等容器服务走向生产环境。两篇文章连起来,单容器和多容器的入门实践就都齐了。

【声明】本内容来自华为云开发者社区博主,不代表华为云及华为云开发者社区的观点和立场。转载时必须标注文章的来源(华为云社区)、文章链接、文章作者等基本信息,否则作者和本社区有权追究责任。如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱: cloudbbs@huaweicloud.com
  • 点赞
  • 收藏
  • 关注作者

评论(0)

0/1000
抱歉,系统识别当前为高风险访问,暂不支持该操作

全部回复

上滑加载中

设置昵称

在此一键设置昵称,即可参与社区互动!

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。