目錄

  • 用 uv 管包 + 用 Docker 跑 Python 項目(實戰總結)
  • 0. 準備工作:虛擬環境與依賴管理
  • 0.1 Conda 和 uv/venv 的關係
  • 0.2 什麼是“凍結依賴”?
  • 0.3 常見報錯與解決
  • 1. Docker 入門:5 條命令夠用
  • 2. Dockerfile 示例(逐行解釋)
  • 3. .env 文件配置規範
  • 4. HuggingFace 緩存掛載
  • 5. 在容器裏運行項目
  • 6. 推薦依賴分層
  • 7. 經驗總結(踩坑清單)
  • 🔚 總結

用 uv 管包 + 用 Docker 跑 Python 項目(實戰總結)

適合場景:Windows/PowerShell 開發、需要“可復現環境”、本地 + 容器雙跑、要用到 HuggingFace 緩存、以及接第三方 OpenAI 兼容 API(如 DashScope/Qwen)。

在做 Python 項目(特別是模型評測、RAG、訓練相關)時,經常會遇到這些痛點:

  • 本地依賴和容器依賴不一致,環境一換就掛;
  • Windows 開發,Linux 容器,某些包(如 pywin32)根本裝不上;
  • HuggingFace 下載慢,鏡像重裝時數據反覆拉取;
  • .env 配置不規範,API Key 或 URL 總是報錯。

我在近期項目中踩過這些坑,最終總結出一套「Conda + uv 管包」+「Docker 部署」的實踐流程。


0. 準備工作:虛擬環境與依賴管理

0.1 Conda 和 uv/venv 的關係

  • Conda 建環境,uv 管包
  • Conda 負責建虛擬環境,解決 Python 版本、CUDA 依賴等底層問題。
  • uv/venv 負責 Python 包安裝速度與依賴解析。
  • 如果你已經在用 Conda 新建了虛擬環境,就不需要再用 uv venv。只要在 Conda 環境裏直接用 uv pip install 即可。

👉 最佳實踐

# 新建 Conda 環境
conda create -n pj310 python=3.10

# 激活環境
conda activate pj310

# 在 Conda 環境裏用 uv 裝包(替代 pip)
uv pip install -r requirements.txt

0.2 什麼是“凍結依賴”?

  • requirements.txt:開發用的主依賴清單(版本可以寬一些)。
  • 凍結依賴(freeze):把當前環境裏實際安裝的所有包及精確版本記錄下來,用於復現或上線。
# 生成凍結依賴(PowerShell)
uv pip freeze --exclude-editable | Out-File -Encoding utf8 requirements-freeze.txt

# 從凍結文件安裝(保證100%一致)
uv pip install -r requirements-freeze.txt

👉 實戰建議:

  • 開發時:用 requirements.txt
  • 上線/歸檔時:生成一份 requirements-freeze.txt

0.3 常見報錯與解決

報錯提示

常見原因

解決方案

No virtual environment found

你在用 uv pip,但沒在 venv/Conda 環境中

先激活環境,或加 --system

No solution found when resolving dependencies

包不兼容(Linux 容器裝 pywin32

分平台 requirements,或用條件依賴:pywin32 ; sys_platform=="win32"

硬鏈接(hardlink)警告

跨盤符複製

可忽略,或設置 $env:UV_LINK_MODE="copy"


1. Docker 入門:5 條命令夠用

先理解幾個概念:

  • 鏡像(Image):打包好的環境 + 程序的模板
  • 容器(Container):鏡像跑起來的實例
  • 構建(build):生成鏡像
  • 運行(run):從鏡像啓動容器

常用命令(夠用版):

# 構建鏡像
docker build -t pj-model-eval:py310 .

# 啓動容器
docker run --rm -it --env-file .env -v "F:\code:/work" pj-model-eval:py310

# 查看運行中的容器
docker ps

# 進入容器
docker exec -it <容器ID> bash

# 停止容器並刪除
docker stop <容器ID> && docker rm <容器ID>

2. Dockerfile 示例(逐行解釋)

# 選擇基礎鏡像:官方 Python 3.10 精簡版
FROM python:3.10-slim

# 安裝系統工具(git、編譯工具鏈),並清理緩存減小體積
RUN apt-get update \
 && apt-get install -y --no-install-recommends git build-essential \
 && rm -rf /var/lib/apt/lists/*

# 設置容器內的工作目錄
WORKDIR /work

# 安裝 uv 並創建虛擬環境(容器內部)
RUN python -m pip install -U pip uv && uv venv /opt/venv
ENV PATH="/opt/venv/bin:$PATH"

# 拷貝依賴清單並安裝(觸發緩存命中)
COPY requirements.txt /tmp/requirements.txt
RUN uv pip install -r /tmp/requirements.txt

# 默認進入 bash
CMD ["bash"]

注意點

  • 容器裏是 Linux,不要把 Windows 包(如 pywin32)寫進 requirements.txt
  • 開發時建議掛載代碼(-v),而不是 COPY 全部項目。

3. .env 文件配置規範

DASHSCOPE_API_KEY=sk-xxxxxxxx

OPENAI_API_KEY=${DASHSCOPE_API_KEY}
OPENAI_BASE_URL=https://dashscope.aliyuncs.com/compatible-mode/v1

EMBEDDING_API_KEY=${DASHSCOPE_API_KEY}
EMBEDDING_BASE_URL=https://dashscope.aliyuncs.com/compatible-mode/v1
EMBEDDING_MODEL=text-embedding-v4

注意

  • 不要加引號
  • 不要寫行內註釋

4. HuggingFace 緩存掛載

避免容器內重複下載模型:

docker run --rm -it `
  --env-file .env `
  -e HF_HOME=/hf_cache `
  -v "F:\hf_cache:/hf_cache" `
  -v "F:\working\pj - model_eval:/work" `
  pj-model-eval:py310

5. 在容器裏運行項目

# 進入容器後執行
python scripts/run_all.py

或分步運行:

python scripts/run_reasoning.py
python scripts/run_rag.py

6. 推薦依賴分層

  1. requirements.txt(通用依賴)
  2. requirements.win.txt(Windows 專屬包,如 pywin32)
  3. requirements-freeze.txt(凍結依賴,保證100%復現)

7. 經驗總結(踩坑清單)

  • .env 文件禁止加引號、註釋
  • Windows 路徑有空格 → 用引號
  • HuggingFace 緩存一定要掛載出來
  • Windows/Linux 依賴分開寫
  • Dockerfile 儘量拆層,緩存命中更快

🔚 總結

我的實踐流程:

  • Conda 建環境 → uv 管包(速度快 + 兼容性好)
  • Docker 復現(可移植 + 不受平台限制)
  • 緩存掛載 + freeze(提速 + 可回滾)

這樣無論是本地開發,還是容器化部署,都能做到穩定、可復現、少踩坑