分阶段构建docker镜像
一个复杂的docker镜像,如果想要一把梭直接构建成功,概率还是很低的。采用分阶段构建的方式,可以在失败中途人肉介入,尝试修正
# ============== 阶段1:安装依赖(易出错步骤) ==============
FROM python:3.11-slim AS deps
WORKDIR /app
# 复制依赖文件(单独复制,利用缓存减少重复安装)
COPY requirements.txt .
COPY pyproject.toml .
# 安装依赖(易出错,单独作为一个阶段)
RUN pip install --no-cache-dir -r requirements.txt && \
pip install hatchling # 解决之前的依赖问题
# 若这一步失败,只需修复后重新构建该阶段
# ============== 阶段2:编译/打包代码(易出错步骤) ==============
FROM deps AS builder # 基于阶段1的结果,避免重复安装依赖
WORKDIR /app
# 复制源代码(代码变更频繁,单独放在这一步)
COPY . .
# 编译或打包(如构建 wheel 包,易出错)
RUN python -m build --wheel # 若失败,仅需重新运行该阶段
# ============== 阶段3:运行环境(最终镜像) ==============
FROM python:3.11-alpine AS runner # 轻量基础镜像
WORKDIR /app
# 从阶段2复制编译好的产物(只复制必要文件,减小体积)
COPY --from=builder /app/dist/*.whl .
# 安装最终产物(步骤简单,不易出错)
RUN pip install --no-cache-dir *.whl
# 启动命令
CMD ["python", "-m", "myapp"]
构建docker镜像到指定的步骤,不需要全部构建
# 只构建到 "deps" 阶段(依赖安装阶段) docker build --target deps --progress=plain -t myapp:deps . # 只构建到 "builder" 阶段(编译阶段) docker build --target builder --progress=plain -t myapp:builder .
中间失败了,从最近一个成功点开始手动执行
# 假设 "deps" 阶段失败,用之前成功的中间镜像调试 docker run -it --rm myapp:deps bash