一、Dockerfile 和 docker-compose.yml 核心作用
1. Dockerfile:构建「可运行的镜像」
Dockerfile 是镜像构建脚本,定义了「运行项目所需的基础环境、依赖、代码、配置」,最终打包成一个独立的 Docker 镜像(镜像 = 项目运行的"完整操作系统+依赖+代码")。简单说,Dockerfile 是"制作镜像的配方"。
2. docker-compose.yml:编排「容器的运行」
Docker Compose 是 Docker 官方的容器编排工具,docker-compose.yml 是它的配置文件,用来定义容器的运行规则 (比如端口映射、数据持久化、环境变量、启动命令、健康检查等),可以一键启动/停止/重启容器,避免手动敲复杂的 docker run 命令。简单说,docker-compose.yml 是"运行容器的说明书"。
二、逐行解析你的文件写法(为什么这么写)
(1)Dockerfile 解析(镜像构建逻辑)
dockerfile
# 基础镜像:轻量版 Python 3.12(slim 减少镜像体积,适合生产环境)
FROM python:3.12-slim
# 环境变量配置(Python 运行最佳实践)
ENV PYTHONDONTWRITEBYTECODE=1 \ # 禁止生成 .pyc 字节码文件(减少冗余)
PYTHONUNBUFFERED=1 \ # 关闭输出缓冲(日志实时打印,方便调试)
PYTHONPATH=/app \ # 设定 Python 根目录(项目代码可直接导入)
TZ=Asia/Shanghai # 设定时区(避免日志/业务时间错乱)
# 设定容器内的工作目录(后续命令都在 /app 下执行)
WORKDIR /app
# 安装系统级依赖(按需安装,最小化原则)
RUN apt-get update && apt-get install -y --no-install-recommends \
build-essential \ # 编译依赖(部分 Python 包带 C 扩展,需编译)
curl \ # 用于 docker-compose 的健康检查(curl 检测接口)
bash \ # 执行启动脚本(start.sh 需要 bash 环境)
supervisor \ # 进程管理(可选,用于管理多进程应用)
&& rm -rf /var/lib/apt/lists/* \ # 清理缓存(减小镜像体积)
&& apt-get clean
# 安装 Python 依赖(先拷贝 requirements.txt 利用 Docker 缓存)
COPY requirements.txt .
RUN pip install --no-cache-dir --upgrade pip -i https://pypi.tuna.tsinghua.edu.cn/simple \
&& pip install --no-cache-dir -r requirements.txt -i https://pypi.tuna.tsinghua.edu.cn/simple
# --no-cache-dir:不缓存安装包(减小镜像体积);清华源:加速国内依赖安装
# 拷贝项目所有代码到容器 /app 目录
COPY . .
# 创建日志/数据目录 + 给启动脚本加执行权限
RUN mkdir -p /app/logs /app/data \
&& chmod +x /app/scripts/*.sh
# 声明容器暴露 8000 端口(仅声明,实际映射靠 docker-compose)
EXPOSE 8000
(2)docker-compose.yml 解析(容器运行逻辑)
yaml
version: '3.8' # Compose 文件格式版本(兼容 Docker 版本)
services:
app: # 定义一个名为 app 的服务(对应一个容器)
image: xmh-docker.tencentcloudcr.com/prod-xmh-ecology-service/ai-expert-hub:latest
# 构建配置:基于当前目录的 Dockerfile 构建镜像
build:
context: . # 构建上下文(Dockerfile 所在目录)
dockerfile: Dockerfile
container_name: ai-expert-hub # 容器名称(固定名称,方便管理)
restart: unless-stopped # 重启策略:除非手动停止,否则容器崩溃自动重启(高可用)
ports:
- "8000:8000" # 端口映射:主机 8000 端口 → 容器 8000 端口(外部可访问)
command: ["bash", "/app/scripts/start.sh"] # 容器启动后执行的命令(运行启动脚本)
environment:
- ENV=${ENV:-prod} # 环境变量:ENV 默认为 prod(项目可根据 ENV 加载不同配置)
volumes:
# 数据卷(持久化 + 热更新):
- /data/log/ai-expert-hub:/app/logs # 主机日志目录 → 容器日志目录(容器删除日志不丢)
- .:/app # 主机当前目录 → 容器 /app(开发时改本地代码,容器内实时同步,无需重构镜像)
healthcheck: # 健康检查(监控服务是否存活)
test: ["CMD", "curl", "-f", "http://localhost:8000/health"] # 检测 /health 接口
interval: 30s # 每 30 秒检查一次
timeout: 10s # 检查超时时间
retries: 3 # 失败重试 3 次判定为不健康
start_period: 10s # 容器启动 10 秒后开始检查
三、两者的配合逻辑
- Dockerfile 做"构建":把项目的运行环境(Python 3.12)、系统依赖(curl/bash)、Python 依赖(requirements.txt)、项目代码打包成一个镜像,这个镜像可以在任何支持 Docker 的机器上运行。
- docker-compose.yml 做"运行" :基于 Dockerfile 构建的镜像,配置容器的运行参数(端口、数据卷、环境变量、启动命令等),然后通过
docker-compose命令一键启动容器,无需手动执行docker build + docker run等复杂命令。
四、搭建完整环境的步骤(从 0 到 1)
前提:安装 Docker + Docker Compose
-
Windows/macOS:安装 Docker Desktop(内置 Compose)。
-
Linux:执行以下命令安装(以 Ubuntu 为例):
bash# 安装 Docker sudo apt-get update && sudo apt-get install -y docker-ce docker-ce-cli containerd.io # 安装 Docker Compose sudo apt-get install -y docker-compose-plugin # 给当前用户加 Docker 权限(避免每次输 sudo) sudo usermod -aG docker $USER && newgrp docker
步骤 1:检查项目文件完整性
确保项目根目录有以下文件/目录(缺一不可):
你的项目/
├── Dockerfile # 镜像构建脚本
├── docker-compose.yml # 容器编排配置
├── requirements.txt # Python 依赖列表(如 fastapi、uvicorn 等)
├── scripts/
│ └── start.sh # 启动脚本(容器核心启动命令)
└── 你的项目代码(如 main.py、app/ 等)
步骤 2:编写启动脚本 start.sh
scripts/start.sh 是容器启动的核心,示例(以 FastAPI 为例,根据你的项目框架调整):
bash
#!/bin/bash
# 可选:添加初始化操作(如数据库迁移、配置检查)
# python /app/manage.py migrate
# 启动 Python 应用(以 uvicorn 为例)
exec uvicorn main:app --host 0.0.0.0 --port 8000
注意:
exec必须加,保证应用进程是容器的 1 号进程(Docker 能正确监控进程状态)。
步骤 3:构建并启动容器
打开终端,进入项目根目录,执行:
bash
# 构建镜像 + 启动容器(后台运行)
docker-compose up -d --build
# 查看容器状态(正常应为 Up)
docker-compose ps
# 查看应用日志(排查启动失败问题)
docker-compose logs -f app
步骤 4:验证服务是否正常
- 访问健康检查接口:
http://localhost:8000/health(需项目实现 /health 接口,返回 200 OK 即正常)。 - 访问应用主接口:
http://localhost:8000(根据你的项目路由调整)。
步骤 5:日常管理命令
bash
# 停止容器(保留镜像/数据)
docker-compose down
# 重启容器
docker-compose restart app
# 进入容器内部调试(比如看代码、查日志)
docker-compose exec app bash
# 重新构建镜像(修改 Dockerfile/requirements.txt 后执行)
docker-compose build app
五、常见问题排查
- 容器启动失败 :执行
docker-compose logs app看日志,常见原因:start.sh不存在/无执行权限(检查脚本路径 +chmod +x scripts/start.sh)。- 端口 8000 被占用(修改
docker-compose.yml的ports为8001:8000)。 - Python 依赖安装失败(检查
requirements.txt语法 + 网络是否能访问清华源)。
- 日志不持久化 :Linux 下给主机日志目录加权限:
sudo chmod 777 /data/log/ai-expert-hub。 - 代码修改后不生效 :确认
volumes里的.:/app配置存在(本地代码映射到容器,改本地代码容器内实时同步)。