Docker 開發
本指南涵蓋 PETsARD 開發者的 Docker 開發設定、測試和部署。
開發環境設定
先決條件
- 已安裝並運行 Docker Desktop
- 已在本地複製 Git 儲存庫
- 對 Docker 概念有基本了解
快速環境檢查
使用基本指令驗證您的 Docker 設定:
# 檢查 Docker 安裝和版本
docker --version
# 檢查 Docker daemon 狀態
docker info
# 測試基本 Docker 功能
docker run --rm hello-world
這將:
- 驗證 Docker 版本
- 檢查 Docker daemon 狀態
- 測試基本 Docker 功能
使用 Docker 進行本地開發
建置本地映像檔
# 建置標準版本(預設 - 不含 Jupyter)
docker build -t petsard:latest .
# 建置包含 Jupyter Lab 的 Jupyter 版本
docker build --build-arg INCLUDE_JUPYTER=true -t petsard:jupyter .
# 針對 ARM64 平台(Apple Silicon)
docker buildx build --platform linux/arm64 --load --build-arg INCLUDE_JUPYTER=true -t petsard:jupyter --no-cache .
運行容器
標準容器
# 運行標準容器(不含 Jupyter)- Python REPL
docker run -it --entrypoint /opt/venv/bin/python3 petsard:latest
# 使用資料卷掛載運行
docker run -it -v $(pwd):/app/data --entrypoint /opt/venv/bin/python3 petsard:latest
Jupyter Lab 容器
# 運行包含 Jupyter Lab 的容器(預設行為)
docker run -it -p 8888:8888 \
-v $(pwd)/data:/app/data \
-v $(pwd)/notebooks:/app/notebooks \
petsard:jupyter
# 在 Jupyter 容器中運行 Python REPL
docker run -it --entrypoint /opt/venv/bin/python3 petsard:jupyter
# 在 http://localhost:8888 存取 Jupyter Lab
特點:
- Jupyter Lab 介面用於互動式開發
- 開放 8888 端口供瀏覽器存取
- 卷掛載以保持資料和 notebook 持久化
- ARM64 優化,適用於 Apple Silicon
開發環境管理
Docker 建置變體
PETsARD 提供靈活的 Docker 建置,可選擇性包含 Jupyter Lab 支援:
# 建置 Jupyter 版本(包含 Jupyter Lab)
docker build --build-arg INCLUDE_JUPYTER=true -t petsard:jupyter .
# 建置標準版本(不含 Jupyter)
docker build --build-arg INCLUDE_JUPYTER=false -t petsard:standard .
# 預設建置(包含 Jupyter)
docker build -t petsard:latest .
Jupyter 版 vs 標準版環境
Jupyter 環境特點
- Jupyter Lab 整合 - 完整的 Jupyter 環境,可在 http://localhost:8888 存取
- 互動式開發 - 卷掛載以進行即時開發
- 完整開發堆疊 - 來自 pyproject.toml [docker] 群組的所有依賴
- 較大映像檔大小 - 包含 Jupyter Lab 和開發工具
# 運行包含 Jupyter Lab 的 Jupyter 容器
docker run -it --rm \
-p 8888:8888 \
-v $(pwd):/workspace \
petsard:jupyter
# 在 http://localhost:8888 存取 Jupyter Lab
標準環境特點
- 核心運行時 - 僅包含 PETsARD 核心功能的必要依賴
- 較小映像檔大小 - 針對部署優化,不含 Jupyter
- 安全優化 - 非 root 使用者執行(UID 1000)
- Distroless 基礎 - 使用 gcr.io/distroless/python3 的最小攻擊面
# 運行標準容器
docker run -it --rm \
-v $(pwd)/data:/app/data \
petsard:standard
配置檔案
Docker 環境使用這些關鍵檔案:
Dockerfile
- 多階段生產優化映像檔,可選擇性支援 Jupyterpyproject.toml
- 專案配置與依賴群組.github/workflows/docker-publish.yml
- 自動建置的 CI/CD 流水線
環境變數
容器會自動配置:
# Python 優化
PYTHONPATH=/app
PYTHONUNBUFFERED=1
PYTHONDONTWRITEBYTECODE=1
# Jupyter 專用(當 INCLUDE_JUPYTER=true 時)
JUPYTER_ENABLE_LAB=yes
JUPYTER_ALLOW_ROOT=1
# 建置變體指示器
INCLUDE_JUPYTER=true/false
開發工作流程
功能開發
設定開發環境
# 建置包含 Jupyter Lab 的 Jupyter 映像檔(ARM64 優化) docker buildx build --platform linux/arm64 --load --build-arg INCLUDE_JUPYTER=true -t petsard:jupyter --no-cache . # 啟動包含 Jupyter Lab 的容器 docker run -it -p 8888:8888 \ -v $(pwd)/data:/app/data \ -v $(pwd)/notebooks:/app/notebooks \ petsard:jupyter # 在 http://localhost:8888 存取 Jupyter Lab
編碼和測試
# 運行 Python REPL 進行測試 docker run -it --entrypoint /opt/venv/bin/python3 petsard:jupyter # 使用資料卷運行測試 docker run -it -v $(pwd):/app/data --entrypoint /opt/venv/bin/python3 petsard:jupyter # 在容器內測試 PETsARD 功能 # python -m petsard.executor demo/tutorial/use-cases/data-constraining.yaml
測試兩種建置變體
# 測試 Jupyter 建置(包含 Jupyter Lab) docker build --build-arg INCLUDE_JUPYTER=true -t petsard:jupyter . # 測試標準建置(預設,不含 Jupyter) docker build -t petsard:latest . # 針對 ARM64 平台 docker buildx build --platform linux/arm64 --load --build-arg INCLUDE_JUPYTER=true -t petsard:jupyter --no-cache .
研究和實驗工作流程
啟動 Jupyter 環境
# 運行包含 Jupyter Lab 的容器 docker run -it --rm \ -p 8888:8888 \ -v $(pwd):/workspace \ petsard:jupyter # 導航至 http://localhost:8888
建立和運行 Notebook
- 使用
/workspace
目錄存放持久化 notebook - 直接存取 PETsARD 模組:
import petsard
- 實驗不同的配置
- 使用
匯出結果
# 存取容器 shell 進行檔案操作 docker run -it --rm \ -v $(pwd):/workspace \ petsard:jupyter \ bash # 您的 notebook 和資料會持久保存在掛載的卷中
測試和驗證
手動測試指令
# 測試基本功能(預設包含 Jupyter)
docker run --rm petsard:latest python -c "
import petsard
import importlib.metadata
print(f'✅ PETsARD v{importlib.metadata.version(\"petsard\")} 已載入')
from petsard.executor import Executor
print('✅ 所有模組匯入成功')
"
# 使用範例配置測試
docker run --rm \
-v $(pwd):/workspace \
-w /workspace \
petsard:latest \
python -m petsard.executor demo/tutorial/use-cases/data-constraining.yaml
# 測試 Jupyter 變體
docker run --rm \
-p 8888:8888 \
-v $(pwd):/workspace \
petsard:jupyter \
python -c "import jupyterlab; print('✅ Jupyter Lab 可用')"
# 測試標準變體
docker run --rm \
petsard:standard \
python -c "import petsard; print('✅ 標準建置正常')"
建置測試
# 測試標準建置(不含 Jupyter)
docker build --build-arg INCLUDE_JUPYTER=false -t petsard:test-standard .
docker run --rm petsard:test-standard python -c "import petsard; print('✅ 標準建置正常')"
# 測試 Jupyter 建置(包含 Jupyter Lab)
docker build --build-arg INCLUDE_JUPYTER=true -t petsard:test-jupyter .
docker run --rm petsard:test-jupyter python -c "import jupyterlab; print('✅ Jupyter 建置正常')"
# 清理測試映像檔
docker rmi petsard:test-standard petsard:test-jupyter
多階段 Dockerfile 架構
Dockerfile 使用多階段建置進行優化:
建置階段
- 基於
python:3.11-slim
- 安裝建置依賴和編譯工具
- 在
/opt/venv
建置虛擬環境 - ARM64 優化 - 針對 Apple Silicon 特別處理 CPU 版本的 PyTorch
- 根據
INCLUDE_JUPYTER
建置參數安裝 PETsARD 與依賴 - 使用
--dependency-groups=docker
安裝 Jupyter Lab
生產階段
- 基於
python:3.11-slim
(非 distroless,以提供更好的相容性) - 建立專用的
petsard
使用者以提高安全性 - 從建置階段複製虛擬環境和應用程式檔案
- 適應性入口腳本,處理 Jupyter 和 Python REPL 模式
- ARM64 效能調校 - 針對 Apple Silicon 優化的環境變數
主要特點
- Python 3.11 - 穩定的 Python 版本,與 anonymeter 相容
- 虛擬環境隔離 - 依賴隔離在
/opt/venv
- ARM64 優化 - 針對 Apple Silicon 特別安裝 CPU 版本的 PyTorch
- 條件性 Jupyter - 基於建置參數的可選 Jupyter Lab
- 非 root 執行 - 以專用的
petsard
使用者運行以提高安全性 - 跨平台支援 - 針對 x86_64 和 ARM64 架構優化
CI/CD 整合
自動建置
專案使用 GitHub Actions 進行自動 Docker 建置:
# 由 semantic release 完成觸發
workflow_run:
workflows: ["Semantic Release"]
types: [completed]
branches: [main, dev]
版本管理
- Semantic Release 整合 - 版本號自動管理
- 動態標籤 - 每次發布創建多個標籤:
latest
(main 分支)v1.4.0
(特定版本)1.4
(主要.次要版本)1
(主要版本)
註冊表發布
映像檔發布到 GitHub Container Registry:
ghcr.io/nics-tw/petsard:latest
ghcr.io/nics-tw/petsard:v1.4.0
除錯問題
檢查容器日誌
# 檢查運行中容器的日誌
docker logs <container_id>
# 即時追蹤日誌
docker logs -f <container_id>
互動式除錯
# 啟動具有除錯存取權限的容器
docker run -it --rm \
-v $(pwd):/workspace \
petsard:jupyter \
bash
# 除錯標準版本
docker run -it --rm \
-v $(pwd):/workspace \
petsard:standard \
python
健康檢查除錯
# 手動健康檢查
docker run --rm petsard:latest python -c "
import importlib.metadata
try:
version = importlib.metadata.version('petsard')
print(f'✅ 健康檢查通過 - PETsARD v{version}')
except Exception as e:
print(f'❌ 健康檢查失敗: {e}')
"
效能優化
建置優化
- 層快取 - Dockerfile 針對 Docker 層快取優化
- 多階段建置 - 更小的最終映像檔
- 依賴快取 - 在程式碼複製前安裝需求
運行時優化
- 虛擬環境 - 隔離的 Python 環境
- 最小基礎映像檔 -
python:3.11-slim
以減少佔用空間 - 非 root 執行 - 安全性和權限優化
疑難排解
常見問題
建置失敗
# 無快取的乾淨建置 docker build --no-cache -t petsard:debug .
權限問題
# 修正檔案權限 docker run --rm -v $(pwd):/workspace \ --user $(id -u):$(id -g) \ petsard:dev chown -R $(id -u):$(id -g) /workspace
記憶體問題
# 增加 Docker 記憶體限制 docker run --memory=4g petsard:dev
環境變數
容器中使用的關鍵環境變數:
# Python 優化
PYTHONPATH=/app
PYTHONUNBUFFERED=1
PYTHONDONTWRITEBYTECODE=1
# Jupyter 專用(當 INCLUDE_JUPYTER=true 時)
JUPYTER_ENABLE_LAB=yes
JUPYTER_ALLOW_ROOT=1
# 建置變體指示器
INCLUDE_JUPYTER=true/false
最佳實踐
- 使用 Docker Compose 進行開發工作流程
- 本地測試 後再推送變更
- 監控映像檔大小 保持最小化
- 使用健康檢查 進行生產部署
- 遵循語義版本控制 進行映像檔標籤
- 記錄環境變數 和配置選項
安全考量
- 非 root 使用者 在生產環境執行
- 最小攻擊面 使用精簡基礎映像檔
- 無硬編碼機密 在 Dockerfile 中
- 定期基礎映像檔更新 以獲得安全修補程式