docker使用uv安装依赖

官方使用

FastAPI 官方 Dockerfile 中用了两次:

python 复制代码
RUN --mount=type=cache,target=/root/.cache/uv \
    --mount=type=bind,source=uv.lock,target=uv.lock \
    --mount=type=bind,source=pyproject.toml,target=pyproject.toml \
    uv sync --frozen --no-install-project  # ✅ 第一次

RUN --mount=type=cache,target=/root/.cache/uv \
    uv sync  # ✅ 第二次

这是 uv 官方推荐的优化构建流程,目的是 最大程度复用缓存,加快构建速度,同时支持源码变化重装依赖。

🔍 第一次 uv sync --frozen --no-install-project

📌 作用是:

• ✅ 只安装依赖(不安装你项目代码)

• ✅ 使用 lock 文件精确控制版本

• ✅ 构建中间层缓存(intermediate layer)

✔️ 只要你没改 pyproject.toml 或 uv.lock,这一层永远不需要重建!

这是 Docker 构建中非常重要的一环 ------ 利用文件不变来缓存 layer,加快构建速度。

🔄 第二次 uv sync

📌 作用是:

• ✅ 安装你项目的源码(也就是 app/ 本身)

• 因为第一次用了 --no-install-project,项目代码没有装进去

🚨 如果你更新了项目源码,但没改 pyproject.toml,就只会触发第二次构建。

你可以类比为:

python 复制代码
# 第一次,只安装依赖,不装项目代码
pip install --no-deps --require-hashes -r requirements.txt

# 第二次,把你的项目当成 package 装进环境里
pip install .
# 是 Python 项目中非常重要的一步,表示 将你当前目录(.)下的项目当作一个 Package 安装到当前 Python 环境中。

这样你每次写代码改的是 .py 文件而不是依赖,Docker 就不会重新构建冗余层 ✅

第一次 uv sync --frozen --no-install-project 第二次 uv sync
安装依赖项(构建缓存层) 安装项目本身
不会安装你 app/ 源码 会装源码到虚拟环境
对应 lock 文件(更可控) 快速重建项目层
有利于构建性能 有利于热更新和本地测试

可以,但你就会失去 中间层缓存优化的好处,每次改 .py 都会重新装全部依赖 ❌

✅ 为什么 FastAPI 官方不写 COPY?

因为他们使用的是 BuildKit 的多阶段构建 + bind mount 优化方案

复制代码
•	第一次 RUN uv sync --frozen --no-install-project 使用挂载的 pyproject.toml 和 uv.lock 安装依赖(但不安装项目)
•	最终会在后面阶段,再使用 COPY . . 把项目代码拷贝进来
步骤 是否合理 说明
设置基础镜像 python:3.12-slim 节省体积
使用 uv 构建 快速高效、现代依赖工具
缓存依赖安装层 加速构建、复用缓存
分阶段 COPY + uv sync 减少变更触发重装
PYTHONPATH=. 适配 from app.xxx 导入
CMD 使用 uvicorn 适合线上部署、ASGI 原生

开箱即用的Dockfile

python 复制代码
FROM python:3.12-slim AS builder

WORKDIR /app

# 设置时区为 UTC+8
ENV TZ=Asia/Shanghai
RUN ln -snf /usr/share/zoneinfo/$TZ /etc/localtime && echo $TZ > /etc/timezone

COPY --from=ghcr.io/astral-sh/uv:0.5.11 /uv /uvx /bin/

ENV PATH="/app/.venv/bin:$PATH"
ENV UV_COMPILE_BYTECODE=1
ENV UV_LINK_MODE=copy

# 复制项目文件到容器中
COPY . /app/

RUN --mount=type=cache,target=/root/.cache/uv \
    --mount=type=bind,source=uv.lock,target=uv.lock \
    --mount=type=bind,source=pyproject.toml,target=pyproject.toml \
    uv sync --frozen --no-install-project

ENV PYTHONPATH=.

CMD ["uvicorn", "app.main:app", "--host", "0.0.0.0", "--port", "8000", "--log-level", "warning"]
相关推荐
梦梦代码精6 小时前
PHP 还是 Java?LikeShop 多版本对比,附6条落地避坑建议
低代码·docker·开源·代码规范
运维大师7 小时前
【K8S 运维实战】15-链路追踪Jaeger与OTel
运维·容器·kubernetes
zerwave7 小时前
深入理解 Docker 的“层”(Layer)
docker·容器
霁月的小屋8 小时前
Docker 工程化实践(二):理解镜像分层与容器文件系统
运维·docker·容器
码上上班1 天前
docker课程
java·docker·容器
lxw18449125141 天前
Python uv 完整使用教程
python·conda·pip·uv
取谖慕12.1 天前
Docker容器从入门到精通
docker·容器·eureka
取谖慕12.1 天前
Harbor仓库从讲解到部署实战
docker·harbor
逍遥德1 天前
运维技术栈Linux+docker+Kubernetes+Jenkins/GitLab CI 知识点详细列表
linux·运维·docker
名字还没想好☜1 天前
Kubernetes CrashLoopBackOff 排查全流程:从 describe 到日志到 exit code
运维·docker·云原生·容器·kubernetes