用 Docker Compose 一条命令跑起一个 Python 小服务

举报
yd_240716394 发表于 2026/10/24 00:14:07 2026/10/24
【摘要】 用 Docker Compose 一条命令跑起带 Redis 的 Python 小服务:从目录结构、Dockerfile 到 compose 编排、健康检查,再到日常运维命令和三个避坑点,新人也能一次跑通。

为什么是 Docker Compose

本地开发最常见的烦恼,是服务依赖散落在各处:数据库要装、缓存要起、环境变量每个人配法还不一样。新人入职第一天,往往半天时间都耗在“把环境跑起来”上。

Docker Compose 就是来解决这个问题的:用一个 YAML 文件把“这个服务需要什么”写清楚,然后一条命令 docker compose up,整套环境原地复活。别人拿到你的项目,也能一键复现同样的运行环境。

准备工作

确认本机已安装 Docker(桌面版自带 Compose 插件):

docker --version
docker compose version

建议 Docker Engine 24 以上,Compose v2。本文所有命令在 Linux / macOS / Windows(WSL2)下通用。

目录结构

compose-demo/
├─ app/
│  ├─ main.py
│  └─ requirements.txt
├─ Dockerfile
└─ docker-compose.yml

第一步:写一个最小的 Python 服务

用 Flask 写一个带健康检查接口的小服务(换成 FastAPI 思路完全一样)。

先写依赖文件 requirements.txt:

Flask==3.0.3
redis==5.0.3

再写服务代码 main.py:

import os
from flask import Flask, jsonify
import redis

app = Flask(__name__)
r = redis.Redis(host=os.getenv("REDIS_HOST", "localhost"), port=6379, decode_responses=True)

@app.get("/")
def index():
    return jsonify(msg="hello from compose", version="1.0")

@app.get("/health")
def health():
    try:
        r.ping()
        redis_ok = True
    except Exception:
        redis_ok = False
    return jsonify(status="ok" if redis_ok else "degraded", redis=redis_ok)

if __name__ == "__main__":
    app.run(host="0.0.0.0", port=8000)

两个要点:监听地址必须写 0.0.0.0 而不是 127.0.0.1,否则容器外访问不到;Redis 地址用环境变量注入,不要写死。

第二步:写 Dockerfile

FROM python:3.12-slim
WORKDIR /code
COPY app/requirements.txt .
RUN pip install --no-cache-dir -r requirements.txt
COPY app/ .
EXPOSE 8000
CMD ["python", "main.py"]

国内构建建议换国内 pip 镜像源,否则下载依赖超时很常见。--no-cache-dir 让镜像更小。

第三步:写 docker-compose.yml

services:
  web:
    build: .
    ports:
      - "8000:8000"
    environment:
      - REDIS_HOST=redis
    depends_on:
      redis:
        condition: service_healthy
    restart: unless-stopped
  redis:
    image: redis:7-alpine
    volumes:
      - redis-data:/data
    healthcheck:
      test: ["CMD", "redis-cli", "ping"]
      interval: 5s
      retries: 5

volumes:
  redis-data:

depends_on 配合 condition: service_healthy,保证 Redis 先就绪再启动 web,避免启动时序竞态。服务之间用“服务名”当主机名互相访问,这里 web 用 REDIS_HOST=redis 就能连上 Redis。

第四步:一条命令跑起来

docker compose up -d --build
docker compose ps

up -d 后台运行,--build 强制重新构建镜像。容器启动后,在浏览器打开本地 8000 端口,访问根路径和 health 健康检查接口,看到 health 返回 status 为 ok 且 redis 为 true,就说明跑通了。

第五步:日常运维小抄

docker compose logs -f web     # 实时跟日志
docker compose restart web    # 重启单个服务
docker compose stop             # 停止所有服务(容器保留)
docker compose down            # 停止并删除容器(数据卷保留)
docker compose down -v         # 连数据卷一起删,慎用

三个常见坑

  1. 端口被占用:把 ports 改成 "8001:8000",换个宿主机端口即可。
  2. 代码改了没生效:构建有缓存,改完 Dockerfile 或依赖后记得加 --build,或用 docker compose build --no-cache。
  3. 容器内连不上依赖:服务间用服务名(如 redis)当主机名,不要写 localhost——localhost 在容器里指的是容器自己。

小结

Docker Compose 把“环境”变成了代码:一个目录、三个文件、一条命令,任何人拿到都能一键复现。熟练之后可以继续加 Nginx 反向代理、Postgres 数据库、定时任务,玩法完全一样。建议把这个 compose-demo 推到自己的代码仓,下次换电脑直接拉代码加一条 up 命令,环境分钟级就绪。

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

评论(0)

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

全部回复

上滑加载中

设置昵称

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

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

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