在项目的包管理上,我觉得没有一个编程语言会比 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.toml和uv.lock文件。此后,就可以通过uv.lock和pyproject.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 文件。