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"]
相关推荐
chen_note1 天前
Dockerfile及其部署镜像步骤
docker·容器·镜像·dockerfile
Jy_06221 天前
K8s中,deployment 是如何从 yaml 文件最终部署成功 pod 的
云原生·容器·kubernetes
mobº1 天前
K8s 集群环境搭建 - yaml 版本(一)
云原生·容器·kubernetes
终端行者1 天前
K8s中部署Minio集群 如何部署minio集群
云原生·容器·kubernetes·1024程序员节
wkj0011 天前
安装了conda和uv如何创建一个项目?
chrome·conda·uv·1024程序员节
杨浦老苏1 天前
开源云文件存储服务器MyDrive
docker·群晖·网盘
PellyKoo1 天前
Docker容器中中文文件名显示乱码问题完美解决方案
运维·docker·容器
无妄无望1 天前
在没有网络的环境下安装包pymysql
学习·docker
奥尔特星云大使1 天前
Docker 拉取 MySQL 5.7 镜像、启动容器并进入 MySQL
数据库·mysql·docker·容器
big男孩1 天前
Docker使用环境变量的整理
docker