GitHub Actions 基础模板
# .github/workflows/ci.yml
name: CI
on: [push, pull_request]
jobs:
test:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Install uv
uses: astral-sh/setup-uv@v3
with:
version: "latest" # 或固定版本 "0.5.0"
enable-cache: true # 启用依赖缓存
- name: Set up Python
run: uv python install 3.13
- name: Sync dependencies
run: uv sync --locked --all-groups
- name: Lint
run: uv run ruff check .
- name: Type check
run: uv run mypy src
- name: Test
run: uv run pytest --cov=src
setup-uv@v3 的好处
① 缓存 ~/.cache/uv(全局 wheel 缓存),二次运行下载几乎为 0。② 以 uv.lock 哈希作为缓存 key,依赖变更时自动失效。③ 自动把 ~/.local/bin 加入 PATH。官方维护,比自己写 cache action 可靠得多。
矩阵测试
jobs:
test:
runs-on: ${{ matrix.os }}
strategy:
fail-fast: false
matrix:
os: [ubuntu-latest, macos-latest, windows-latest]
python: ["3.11", "3.12", "3.13"]
steps:
- uses: actions/checkout@v4
- uses: astral-sh/setup-uv@v3
with:
enable-cache: true
- run: uv python install ${{ matrix.python }}
- run: uv sync --locked --python ${{ matrix.python }}
- run: uv run pytest
uv 官方 Docker 镜像
Astral 提供了好几种 Docker 镜像,选择看需求:
| 镜像 | 大小 | 用途 |
|---|---|---|
ghcr.io/astral-sh/uv:latest | ~25MB | 只含 uv 二进制,当工具用 |
ghcr.io/astral-sh/uv:python3.13-bookworm-slim | ~50MB | uv + 精简 Debian + 预装 Python |
ghcr.io/astral-sh/uv:python3.13-alpine | ~40MB | 基于 Alpine,最小 |
ghcr.io/astral-sh/uv:debian-slim | ~45MB | uv + Debian,自己装 Python |
单阶段 Dockerfile(简单场景)
FROM ghcr.io/astral-sh/uv:python3.13-bookworm-slim
WORKDIR /app
# 复制依赖声明先
COPY pyproject.toml uv.lock ./
# 同步依赖(不装自身代码)
RUN uv sync --frozen --no-dev --no-install-project
# 再复制应用代码
COPY . .
# 最后装自身(editable,改代码不用重装依赖)
RUN uv sync --frozen --no-dev
# 运行
ENV PATH="/app/.venv/bin:$PATH"
CMD ["uvicorn", "app.main:app", "--host", "0.0.0.0"]
分层构建的关键
先 COPY pyproject.toml uv.lock 再 COPY .,利用 Docker 层缓存——只要依赖没变,代码改动不会触发重装依赖。这一个技巧能把构建时间从几十秒压到几秒。
多阶段构建(生产推荐)
# ---------- Build stage ----------
FROM ghcr.io/astral-sh/uv:python3.13-bookworm-slim AS builder
WORKDIR /app
ENV UV_COMPILE_BYTECODE=1 \
UV_LINK_MODE=copy \
UV_PYTHON_DOWNLOADS=never
COPY pyproject.toml uv.lock ./
RUN --mount=type=cache,target=/root/.cache/uv \
uv sync --frozen --no-dev --no-install-project
COPY . .
RUN uv sync --frozen --no-dev
# ---------- Runtime stage ----------
FROM python:3.13-slim-bookworm
WORKDIR /app
COPY --from=builder /app/.venv /app/.venv
COPY --from=builder /app /app
ENV PATH="/app/.venv/bin:$PATH"
USER 1000:1000
CMD ["uvicorn", "app.main:app", "--host", "0.0.0.0"]
关键环境变量:
- UV_COMPILE_BYTECODE=1:安装时预编译 .pyc,冷启动快几十毫秒。
- UV_LINK_MODE=copy:Docker 跨层硬链接不行,改用复制。
- UV_PYTHON_DOWNLOADS=never:生产镜像已经有 Python,禁止联网下。
- --mount=type=cache:BuildKit 缓存挂载,跨构建复用 wheel 缓存。
更极致的瘦身:distroless
FROM ghcr.io/astral-sh/uv:python3.13-bookworm-slim AS builder
WORKDIR /app
COPY pyproject.toml uv.lock ./
RUN uv sync --frozen --no-dev --no-install-project
COPY . .
RUN uv sync --frozen --no-dev
# Google distroless:只有 Python 运行时,没有 shell
FROM gcr.io/distroless/python3-debian12
COPY --from=builder /app /app
WORKDIR /app
ENV PATH="/app/.venv/bin:$PATH"
ENTRYPOINT ["/app/.venv/bin/python", "-m", "app"]
distroless 镜像没有 bash、apt,不能 docker exec -it 调试,但攻击面小 10 倍,生产安全推荐。
uv export 兼容老工作流
如果你的 CI/部署系统只认 requirements.txt(比如某些云的 Python 运行时),可导出:
uv export --format requirements-txt --no-dev > requirements.txt
uv export --format requirements-txt --all-extras > requirements-full.txt
uv export --format pylock.toml > pylock.toml # PEP 751 新格式
从 pip + requirements.txt 迁移
# 1. 初始化项目
cd existing-project
uv init --package .
# 2. 导入 requirements.txt 为依赖
uv add -r requirements.txt
# 3. 如果有 requirements-dev.txt
uv add --dev -r requirements-dev.txt
# 4. 删除老文件
rm requirements.txt requirements-dev.txt
rm -rf venv/ # 旧虚拟环境
# 5. 跑一遍 sync 验证
uv sync
uv run pytest
从 Poetry 迁移
# uv 不原生读取 poetry 配置,但 pyproject.toml 的 [project] 是标准的
# Poetry 的配置在 [tool.poetry],需要手动迁移
# 1. 把 [tool.poetry].dependencies 改写为 [project].dependencies
# 2. 把 [tool.poetry.dev-dependencies] 改为 [dependency-groups].dev
# 3. 删除 poetry.lock
rm poetry.lock
# 4. 生成新 lock
uv lock
uv sync
社区工具 migrate-to-uv(uvx migrate-to-uv)可一键迁移 Poetry/PDM/Pipenv/Hatch 项目。
迁移对照表
| 原命令 | uv 等价 |
|---|---|
pip install pkg | uv add pkg |
pip install -r requirements.txt | uv sync |
pip install -e . | 自动完成(uv sync) |
pip list | uv tree --depth 1 或 uv pip list |
pip freeze | uv export --format requirements-txt |
python -m venv .venv | uv venv |
source .venv/bin/activate + python x.py | uv run python x.py |
pipx install black | uv tool install black |
pipx run cowsay | uvx cowsay |
pyenv install 3.13 | uv python install 3.13 |
poetry add pkg | uv add pkg |
poetry install | uv sync |
poetry run x | uv run x |
poetry build | uv build |
poetry publish | uv publish |
GitLab CI / Jenkins 模板
# .gitlab-ci.yml
image: ghcr.io/astral-sh/uv:python3.13-bookworm-slim
variables:
UV_CACHE_DIR: ".uv-cache"
cache:
key:
files:
- uv.lock
paths:
- .uv-cache/
test:
script:
- uv sync --locked
- uv run pytest
监控 uv 自身版本
# 建议固定 uv 版本,避免自动升级引入不兼容
# setup-uv 里
- uses: astral-sh/setup-uv@v3
with:
version: "0.5.0" # 精确到小版本
全书总结
十章走完,uv 的全部能力已覆盖:① 安装与对比 ② pyproject.toml 标准 ③ 依赖管理循环 ④ 锁文件原理 ⑤ Python 多版本 ⑥ uv run 免激活 ⑦ 全局工具 ⑧ Monorepo 工作区 ⑨ PyTorch 多索引 ⑩ CI/CD 部署。今天就把手头的项目从 pip/poetry 迁到 uv,节省下来的时间会让你惊讶。