在项目的包管理上,我觉得没有一个编程语言会比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
锁定包依赖了。
# 构建阶段
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文件。