如何使用uv作为python项目的包管理工具

Database and Ruby, Python, History


在项目的包管理上,我觉得没有一个编程语言会比 Python 更让人抓狂的。

  • 有一个 requirements.txt 文件,却没有一个好用的,锁定包版本的 requirements.txt.lock 文件,你需要安装poetry或者uv
  • 你可以用pip frozen去更新 requirements.txt,但却加入了很多项目并不需要的包

我倒是更喜欢前端工具yarn,比如yarn add就自动更新 package.json 和 package.json.lock 文件,锁定版本。

对应到 Python,直到用了uv

使用 Conda 作为 Python 版本工具

对比其他语言,可以有下面的 mapping 关系

  Language   Version Management   Package Management  
Ruby rbenv bundle        
Node.js nvm/fnm npm/yarn        
Python pyenv/conda poetry/uv        

使用 uv

对于一个项目,直接uv init .初始化当前项目,会生成 pyproject.toml 文件。此后需要使用uv add package在添加 package,就会自动更新pyproject.tomluv.lock文件。此后,就可以通过uv.lockpyproject.toml锁定包依赖了。

通过 source .venv/bin/activate 激活当前虚拟环境的 Python。

使用 uv 的 venv

source .venv/bin/activate
# 构建阶段
FROM python:3.12-slim-bookworm AS builder

# 复制 uv 工具
COPY --from=ghcr.io/astral-sh/uv:latest /uv /usr/local/bin/uv

# 设置 uv 的环境变量
ENV UV_COMPILE_BYTECODE=1 \
    UV_LINK_MODE=copy

# 设置工作目录
WORKDIR /app

# 首先只复制依赖相关文件
COPY uv.lock pyproject.toml /app/

# 安装依赖
RUN --mount=type=cache,target=/root/.cache/uv \
    uv sync --frozen --no-install-project --no-dev

# 复制项目代码和uwsgi配置
COPY . /app

# 安装项目
RUN --mount=type=cache,target=/root/.cache/uv \
    uv sync --frozen --no-dev

# 最终镜像
FROM python:3.12-slim-bookworm

# 从构建阶段复制整个应用(包括虚拟环境)
COPY --from=builder /app /app

# 设置环境变量使虚拟环境生效
ENV PATH="/app/.venv/bin:$PATH"

# 设置工作目录
WORKDIR /app

# 暴露端口
EXPOSE 5000

# 启动命令
CMD ["uwsgi", "--ini", "uwsgi.ini"]

如果还需要兼容 requirements.txt,可以使用uv pip compile pyproject.toml -o requirements.txt去更新 requirements.txt 文件。