feat: 完全離線化 Dockerfile v0.1.16
## 主要修復 - MinerU: 改用 system-level 安裝 (uv pip install --system) - MinerU: 模型下載到固定目錄 /opt/mineru/models - BabelDOC: 完整 warmup + 離線 cache - PDFMathTranslate: ONNX 模型使用 COPY 指令 - ImageMagick: 確保已安裝 ## 結構優化 - Multi-Stage Build (8 stages) - 使用 heredoc 語法處理多行 Python - 分階段安裝避免記憶體尖峰 ## Runtime 離線模式 - HF_HOME=/nonexistent - HF_HUB_OFFLINE=1 - BABELDOC_OFFLINE=1 - PIP_NO_INDEX=1 ## 新增驗證腳本 - scripts/verify-offline.sh
This commit is contained in:
parent
b23d42a7b1
commit
367e0d3056
4 changed files with 1682 additions and 761 deletions
|
|
@ -1,6 +1,6 @@
|
|||
#!/bin/bash
|
||||
# ==============================================================================
|
||||
# ConvertX-CN 模型驗證腳本
|
||||
# ConvertX-CN 模型驗證腳本 v2.0
|
||||
# ==============================================================================
|
||||
#
|
||||
# 用途:驗證 Docker Image 中的預下載模型是否完整
|
||||
|
|
@ -11,7 +11,7 @@
|
|||
set -e
|
||||
|
||||
echo "========================================"
|
||||
echo "🔍 ConvertX-CN 模型驗證"
|
||||
echo "🔍 ConvertX-CN 模型驗證 v2.0"
|
||||
echo "========================================"
|
||||
echo ""
|
||||
|
||||
|
|
@ -19,6 +19,7 @@ echo ""
|
|||
PASS=0
|
||||
FAIL=0
|
||||
WARN=0
|
||||
ARCH=$(uname -m)
|
||||
|
||||
# 檢查函數
|
||||
check_file() {
|
||||
|
|
@ -37,22 +38,28 @@ check_file() {
|
|||
check_dir() {
|
||||
local path="$1"
|
||||
local name="$2"
|
||||
local required="${3:-false}"
|
||||
if [ -d "$path" ]; then
|
||||
local size=$(du -sh "$path" 2>/dev/null | awk '{print $1}')
|
||||
echo "✅ $name: $path ($size)"
|
||||
((PASS++))
|
||||
else
|
||||
echo "⚠️ $name: $path 不存在"
|
||||
((WARN++))
|
||||
if [ "$required" = "true" ]; then
|
||||
echo "❌ $name: $path 不存在(必要)"
|
||||
((FAIL++))
|
||||
else
|
||||
echo "⚠️ $name: $path 不存在(可選)"
|
||||
((WARN++))
|
||||
fi
|
||||
fi
|
||||
}
|
||||
|
||||
# ==============================================================================
|
||||
# 1. PDFMathTranslate 模型
|
||||
# 1. PDFMathTranslate / BabelDOC ONNX 模型
|
||||
# ==============================================================================
|
||||
echo "📦 PDFMathTranslate 模型"
|
||||
echo "📦 PDFMathTranslate / BabelDOC 模型"
|
||||
echo "----------------------------------------"
|
||||
check_file "/models/pdfmathtranslate/model.onnx" "DocLayout-YOLO ONNX"
|
||||
check_file "/root/.cache/babeldoc/models/doclayout_yolo_docstructbench_imgsz1024.onnx" "DocLayout-YOLO ONNX"
|
||||
echo ""
|
||||
|
||||
# ==============================================================================
|
||||
|
|
@ -60,20 +67,25 @@ echo ""
|
|||
# ==============================================================================
|
||||
echo "🔤 PDFMathTranslate 字型"
|
||||
echo "----------------------------------------"
|
||||
check_file "/app/GoNotoKurrent-Regular.ttf" "Noto 通用字型"
|
||||
check_file "/app/SourceHanSerifCN-Regular.ttf" "思源宋體(簡體)"
|
||||
check_file "/app/SourceHanSerifTW-Regular.ttf" "思源宋體(繁體)"
|
||||
check_file "/app/SourceHanSerifJP-Regular.ttf" "思源宋體(日文)"
|
||||
check_file "/app/SourceHanSerifKR-Regular.ttf" "思源宋體(韓文)"
|
||||
check_file "/usr/share/fonts/truetype/custom/GoNotoKurrent-Regular.ttf" "Noto 通用字型"
|
||||
check_file "/usr/share/fonts/truetype/custom/SourceHanSerifCN-Regular.ttf" "思源宋體(簡體)"
|
||||
check_file "/usr/share/fonts/truetype/custom/SourceHanSerifTW-Regular.ttf" "思源宋體(繁體)"
|
||||
check_file "/usr/share/fonts/truetype/custom/SourceHanSerifJP-Regular.ttf" "思源宋體(日文)"
|
||||
check_file "/usr/share/fonts/truetype/custom/SourceHanSerifKR-Regular.ttf" "思源宋體(韓文)"
|
||||
echo ""
|
||||
|
||||
# ==============================================================================
|
||||
# 3. MinerU 模型
|
||||
# 3. MinerU 模型(新路徑:/opt/mineru)
|
||||
# ==============================================================================
|
||||
echo "📦 MinerU 模型"
|
||||
echo "----------------------------------------"
|
||||
check_dir "/root/.cache/huggingface/hub/PDF-Extract-Kit-1.0" "PDF-Extract-Kit-1.0 Pipeline"
|
||||
check_dir "/root/.cache/huggingface/hub/MinerU-VLM" "MinerU VLM(可選)"
|
||||
if [ "$ARCH" = "aarch64" ]; then
|
||||
echo "⚠️ ARM64 架構:MinerU 不支援,跳過驗證"
|
||||
((WARN++))
|
||||
else
|
||||
check_dir "/opt/mineru/models/PDF-Extract-Kit-1.0" "PDF-Extract-Kit-1.0 Pipeline" "true"
|
||||
check_file "/root/mineru.json" "MinerU 配置檔"
|
||||
fi
|
||||
echo ""
|
||||
|
||||
# ==============================================================================
|
||||
|
|
@ -81,25 +93,22 @@ echo ""
|
|||
# ==============================================================================
|
||||
echo "📦 BabelDOC 快取"
|
||||
echo "----------------------------------------"
|
||||
if [ -d "/root/.cache/babeldoc" ]; then
|
||||
check_dir "/root/.cache/babeldoc" "BabelDOC 快取"
|
||||
elif [ -d "/root/.local/share/babeldoc" ]; then
|
||||
check_dir "/root/.local/share/babeldoc" "BabelDOC 資料"
|
||||
else
|
||||
echo "⚠️ BabelDOC 快取目錄未找到(可能使用其他路徑)"
|
||||
((WARN++))
|
||||
fi
|
||||
check_dir "/root/.cache/babeldoc" "BabelDOC 快取"
|
||||
check_dir "/root/.cache/babeldoc/models" "BabelDOC Models"
|
||||
check_dir "/root/.cache/babeldoc/fonts" "BabelDOC Fonts"
|
||||
echo ""
|
||||
|
||||
# ==============================================================================
|
||||
# 5. 環境變數檢查
|
||||
# 5. 環境變數檢查(離線模式)
|
||||
# ==============================================================================
|
||||
echo "🔧 環境變數"
|
||||
echo "🔧 環境變數(離線模式)"
|
||||
echo "----------------------------------------"
|
||||
echo "PDFMATHTRANSLATE_MODELS_PATH: ${PDFMATHTRANSLATE_MODELS_PATH:-未設定}"
|
||||
echo "NOTO_FONT_PATH: ${NOTO_FONT_PATH:-未設定}"
|
||||
echo "MINERU_MODEL_SOURCE: ${MINERU_MODEL_SOURCE:-未設定}"
|
||||
echo "HF_HUB_OFFLINE: ${HF_HUB_OFFLINE:-未設定}"
|
||||
echo "TRANSFORMERS_OFFLINE: ${TRANSFORMERS_OFFLINE:-未設定}"
|
||||
echo "HF_HOME: ${HF_HOME:-未設定}"
|
||||
echo "MINERU_MODEL_SOURCE: ${MINERU_MODEL_SOURCE:-未設定}"
|
||||
echo "BABELDOC_OFFLINE: ${BABELDOC_OFFLINE:-未設定}"
|
||||
echo "PIP_NO_INDEX: ${PIP_NO_INDEX:-未設定}"
|
||||
echo ""
|
||||
|
||||
# ==============================================================================
|
||||
|
|
@ -107,16 +116,40 @@ echo ""
|
|||
# ==============================================================================
|
||||
echo "📝 MinerU 設定檔"
|
||||
echo "----------------------------------------"
|
||||
if [ -f "/root/mineru.json" ]; then
|
||||
if [ "$ARCH" = "aarch64" ]; then
|
||||
echo "⚠️ ARM64 架構:跳過 MinerU 配置驗證"
|
||||
((WARN++))
|
||||
elif [ -f "/root/mineru.json" ]; then
|
||||
echo "✅ /root/mineru.json 存在"
|
||||
cat /root/mineru.json
|
||||
((PASS++))
|
||||
else
|
||||
echo "⚠️ /root/mineru.json 不存在"
|
||||
((WARN++))
|
||||
echo "❌ /root/mineru.json 不存在"
|
||||
((FAIL++))
|
||||
fi
|
||||
echo ""
|
||||
|
||||
# ==============================================================================
|
||||
# 7. 工具可執行性驗證
|
||||
# ==============================================================================
|
||||
echo "🔧 工具可執行性"
|
||||
echo "----------------------------------------"
|
||||
for cmd in mineru babeldoc pdf2zh markitdown convert ffmpeg pandoc; do
|
||||
if command -v "$cmd" >/dev/null 2>&1; then
|
||||
echo "✅ $cmd: $(which $cmd)"
|
||||
((PASS++))
|
||||
else
|
||||
if [ "$cmd" = "mineru" ] && [ "$ARCH" = "aarch64" ]; then
|
||||
echo "⚠️ $cmd: ARM64 不支援"
|
||||
((WARN++))
|
||||
else
|
||||
echo "⚠️ $cmd: 未找到"
|
||||
((WARN++))
|
||||
fi
|
||||
fi
|
||||
done
|
||||
echo ""
|
||||
|
||||
# ==============================================================================
|
||||
# 總結
|
||||
# ==============================================================================
|
||||
|
|
@ -134,7 +167,7 @@ if [ $FAIL -gt 0 ]; then
|
|||
exit 1
|
||||
elif [ $WARN -gt 0 ]; then
|
||||
echo "⚠️ 驗證完成,但有警告。"
|
||||
echo " 部分可選模型可能需要 runtime 下載。"
|
||||
echo " 部分可選功能可能需要確認。"
|
||||
exit 0
|
||||
else
|
||||
echo "✅ 所有模型驗證通過!"
|
||||
|
|
|
|||
310
scripts/verify-offline.sh
Normal file
310
scripts/verify-offline.sh
Normal file
|
|
@ -0,0 +1,310 @@
|
|||
#!/bin/bash
|
||||
# ==============================================================================
|
||||
# ConvertX-CN 離線驗證腳本 v2.0
|
||||
# ==============================================================================
|
||||
#
|
||||
# 用途:驗證 Docker Image 在完全離線環境下可正常運作
|
||||
# 執行方式:
|
||||
# 1. 容器內執行:/app/scripts/verify-offline.sh
|
||||
# 2. 網路隔離測試:docker run --network=none <image> /app/scripts/verify-offline.sh
|
||||
#
|
||||
# 驗證項目:
|
||||
# 1. MinerU:可執行 + 模型存在 + 配置正確
|
||||
# 2. BabelDOC:可執行 + cache 存在
|
||||
# 3. PDFMathTranslate (pdf2zh):可執行 + ONNX 模型存在
|
||||
# 4. ImageMagick:可執行
|
||||
# 5. 字型:自訂字型已安裝
|
||||
# 6. 環境變數:離線模式已正確設定
|
||||
#
|
||||
# ==============================================================================
|
||||
|
||||
set -e
|
||||
|
||||
echo ""
|
||||
echo "╔══════════════════════════════════════════════════════════════════════╗"
|
||||
echo "║ ConvertX-CN 離線驗證腳本 v2.0 ║"
|
||||
echo "║ Runtime Zero-Download Verification ║"
|
||||
echo "╚══════════════════════════════════════════════════════════════════════╝"
|
||||
echo ""
|
||||
|
||||
# 計數器
|
||||
PASS=0
|
||||
FAIL=0
|
||||
WARN=0
|
||||
ARCH=$(uname -m)
|
||||
|
||||
# 顏色定義
|
||||
RED='\033[0;31m'
|
||||
GREEN='\033[0;32m'
|
||||
YELLOW='\033[1;33m'
|
||||
NC='\033[0m' # No Color
|
||||
|
||||
# 檢查函數
|
||||
pass() {
|
||||
echo -e "${GREEN}✅ $1${NC}"
|
||||
((PASS++))
|
||||
}
|
||||
|
||||
fail() {
|
||||
echo -e "${RED}❌ $1${NC}"
|
||||
((FAIL++))
|
||||
}
|
||||
|
||||
warn() {
|
||||
echo -e "${YELLOW}⚠️ $1${NC}"
|
||||
((WARN++))
|
||||
}
|
||||
|
||||
info() {
|
||||
echo -e " ℹ️ $1"
|
||||
}
|
||||
|
||||
check_command() {
|
||||
local cmd="$1"
|
||||
local name="$2"
|
||||
if command -v "$cmd" >/dev/null 2>&1; then
|
||||
pass "$name 可執行: $(which $cmd)"
|
||||
return 0
|
||||
else
|
||||
fail "$name 未安裝或不在 PATH"
|
||||
return 1
|
||||
fi
|
||||
}
|
||||
|
||||
check_file() {
|
||||
local path="$1"
|
||||
local name="$2"
|
||||
if [ -f "$path" ]; then
|
||||
local size=$(ls -lh "$path" 2>/dev/null | awk '{print $5}')
|
||||
pass "$name: $path ($size)"
|
||||
return 0
|
||||
else
|
||||
fail "$name: $path 不存在"
|
||||
return 1
|
||||
fi
|
||||
}
|
||||
|
||||
check_dir() {
|
||||
local path="$1"
|
||||
local name="$2"
|
||||
local required="${3:-false}"
|
||||
if [ -d "$path" ]; then
|
||||
local size=$(du -sh "$path" 2>/dev/null | awk '{print $1}')
|
||||
pass "$name: $path ($size)"
|
||||
return 0
|
||||
else
|
||||
if [ "$required" = "true" ]; then
|
||||
fail "$name: $path 不存在(必要)"
|
||||
else
|
||||
warn "$name: $path 不存在(可選)"
|
||||
fi
|
||||
return 1
|
||||
fi
|
||||
}
|
||||
|
||||
check_env() {
|
||||
local var="$1"
|
||||
local expected="$2"
|
||||
local actual="${!var}"
|
||||
if [ -n "$actual" ]; then
|
||||
if [ -n "$expected" ] && [ "$actual" != "$expected" ]; then
|
||||
warn "$var = $actual(預期: $expected)"
|
||||
else
|
||||
pass "$var = $actual"
|
||||
fi
|
||||
else
|
||||
warn "$var 未設定"
|
||||
fi
|
||||
}
|
||||
|
||||
# ==============================================================================
|
||||
echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
|
||||
echo "📦 1. MinerU 驗證"
|
||||
echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
|
||||
# ==============================================================================
|
||||
|
||||
if [ "$ARCH" = "aarch64" ]; then
|
||||
warn "ARM64 架構:MinerU 不支援,跳過驗證"
|
||||
else
|
||||
# 檢查 mineru 命令
|
||||
check_command "mineru" "MinerU CLI"
|
||||
|
||||
# 檢查模型目錄
|
||||
MINERU_MODELS="/opt/mineru/models/PDF-Extract-Kit-1.0"
|
||||
check_dir "$MINERU_MODELS" "MinerU Pipeline 模型" "true"
|
||||
|
||||
# 檢查配置檔
|
||||
if check_file "/root/mineru.json" "MinerU 配置檔"; then
|
||||
info "配置內容:"
|
||||
cat /root/mineru.json 2>/dev/null | head -10
|
||||
fi
|
||||
|
||||
# 驗證配置指向正確目錄
|
||||
if [ -f "/root/mineru.json" ]; then
|
||||
CONFIGURED_PATH=$(python3 -c "import json; f=open('/root/mineru.json'); d=json.load(f); print(d.get('models-dir',{}).get('pipeline',''))" 2>/dev/null || echo "")
|
||||
if [ "$CONFIGURED_PATH" = "$MINERU_MODELS" ]; then
|
||||
pass "mineru.json 指向正確目錄"
|
||||
else
|
||||
fail "mineru.json 指向錯誤目錄: $CONFIGURED_PATH"
|
||||
fi
|
||||
fi
|
||||
fi
|
||||
echo ""
|
||||
|
||||
# ==============================================================================
|
||||
echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
|
||||
echo "📦 2. BabelDOC 驗證"
|
||||
echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
|
||||
# ==============================================================================
|
||||
|
||||
check_command "babeldoc" "BabelDOC CLI"
|
||||
|
||||
# 檢查 cache 目錄
|
||||
check_dir "/root/.cache/babeldoc" "BabelDOC Cache"
|
||||
check_dir "/root/.cache/babeldoc/models" "BabelDOC Models"
|
||||
check_dir "/root/.cache/babeldoc/fonts" "BabelDOC Fonts"
|
||||
|
||||
# 檢查 ONNX 模型
|
||||
BABELDOC_ONNX="/root/.cache/babeldoc/models/doclayout_yolo_docstructbench_imgsz1024.onnx"
|
||||
check_file "$BABELDOC_ONNX" "DocLayout-YOLO ONNX"
|
||||
|
||||
# 測試 babeldoc --help(不應觸發下載)
|
||||
if command -v babeldoc >/dev/null 2>&1; then
|
||||
if timeout 10 babeldoc --help >/dev/null 2>&1; then
|
||||
pass "babeldoc --help 可離線執行"
|
||||
else
|
||||
warn "babeldoc --help 執行異常"
|
||||
fi
|
||||
fi
|
||||
echo ""
|
||||
|
||||
# ==============================================================================
|
||||
echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
|
||||
echo "📦 3. PDFMathTranslate (pdf2zh) 驗證"
|
||||
echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
|
||||
# ==============================================================================
|
||||
|
||||
check_command "pdf2zh" "pdf2zh CLI"
|
||||
|
||||
# 測試 pdf2zh --help
|
||||
if command -v pdf2zh >/dev/null 2>&1; then
|
||||
if timeout 10 pdf2zh --help >/dev/null 2>&1; then
|
||||
pass "pdf2zh --help 可離線執行"
|
||||
else
|
||||
warn "pdf2zh --help 執行異常"
|
||||
fi
|
||||
fi
|
||||
echo ""
|
||||
|
||||
# ==============================================================================
|
||||
echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
|
||||
echo "📦 4. ImageMagick 驗證"
|
||||
echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
|
||||
# ==============================================================================
|
||||
|
||||
if check_command "convert" "ImageMagick (convert)"; then
|
||||
VERSION=$(convert --version 2>/dev/null | head -1)
|
||||
info "版本: $VERSION"
|
||||
fi
|
||||
|
||||
check_command "identify" "ImageMagick (identify)"
|
||||
check_command "mogrify" "ImageMagick (mogrify)"
|
||||
echo ""
|
||||
|
||||
# ==============================================================================
|
||||
echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
|
||||
echo "🔤 5. 字型驗證"
|
||||
echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
|
||||
# ==============================================================================
|
||||
|
||||
CUSTOM_FONTS_DIR="/usr/share/fonts/truetype/custom"
|
||||
if check_dir "$CUSTOM_FONTS_DIR" "自訂字型目錄"; then
|
||||
FONT_COUNT=$(ls -1 "$CUSTOM_FONTS_DIR"/*.ttf 2>/dev/null | wc -l)
|
||||
info "字型檔案數量: $FONT_COUNT"
|
||||
ls -1 "$CUSTOM_FONTS_DIR"/*.ttf 2>/dev/null | while read f; do
|
||||
info " - $(basename $f)"
|
||||
done
|
||||
fi
|
||||
|
||||
# 驗證必要字型
|
||||
check_file "$CUSTOM_FONTS_DIR/GoNotoKurrent-Regular.ttf" "Noto 通用字型"
|
||||
check_file "$CUSTOM_FONTS_DIR/SourceHanSerifCN-Regular.ttf" "思源宋體(簡體)"
|
||||
check_file "$CUSTOM_FONTS_DIR/SourceHanSerifTW-Regular.ttf" "思源宋體(繁體)"
|
||||
check_file "$CUSTOM_FONTS_DIR/SourceHanSerifJP-Regular.ttf" "思源宋體(日文)"
|
||||
check_file "$CUSTOM_FONTS_DIR/SourceHanSerifKR-Regular.ttf" "思源宋體(韓文)"
|
||||
echo ""
|
||||
|
||||
# ==============================================================================
|
||||
echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
|
||||
echo "🔧 6. 離線環境變數驗證"
|
||||
echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
|
||||
# ==============================================================================
|
||||
|
||||
echo "📋 HuggingFace 離線設定:"
|
||||
check_env "HF_HUB_OFFLINE" "1"
|
||||
check_env "TRANSFORMERS_OFFLINE" "1"
|
||||
check_env "HF_DATASETS_OFFLINE" "1"
|
||||
check_env "HF_HOME" "/nonexistent"
|
||||
check_env "TRANSFORMERS_CACHE" "/nonexistent"
|
||||
|
||||
echo ""
|
||||
echo "📋 MinerU 設定:"
|
||||
check_env "MINERU_MODEL_SOURCE" "local"
|
||||
check_env "MINERU_CONFIG"
|
||||
|
||||
echo ""
|
||||
echo "📋 BabelDOC 設定:"
|
||||
check_env "BABELDOC_OFFLINE" "1"
|
||||
check_env "BABELDOC_CACHE_PATH"
|
||||
|
||||
echo ""
|
||||
echo "📋 pip 設定:"
|
||||
check_env "PIP_NO_INDEX" "1"
|
||||
echo ""
|
||||
|
||||
# ==============================================================================
|
||||
echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
|
||||
echo "🔧 7. 其他核心工具驗證"
|
||||
echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
|
||||
# ==============================================================================
|
||||
|
||||
check_command "ffmpeg" "FFmpeg"
|
||||
check_command "pandoc" "Pandoc"
|
||||
check_command "libreoffice" "LibreOffice"
|
||||
check_command "tesseract" "Tesseract OCR"
|
||||
check_command "gs" "Ghostscript"
|
||||
check_command "inkscape" "Inkscape"
|
||||
check_command "markitdown" "MarkItDown"
|
||||
echo ""
|
||||
|
||||
# ==============================================================================
|
||||
echo ""
|
||||
echo "╔══════════════════════════════════════════════════════════════════════╗"
|
||||
echo "║ 驗證結果總結 ║"
|
||||
echo "╚══════════════════════════════════════════════════════════════════════╝"
|
||||
echo ""
|
||||
echo " ✅ 通過: $PASS"
|
||||
echo " ⚠️ 警告: $WARN"
|
||||
echo " ❌ 失敗: $FAIL"
|
||||
echo ""
|
||||
|
||||
if [ $FAIL -gt 0 ]; then
|
||||
echo -e "${RED}╔══════════════════════════════════════════════════════════════════════╗${NC}"
|
||||
echo -e "${RED}║ ❌ 離線驗證失敗! ║${NC}"
|
||||
echo -e "${RED}║ 部分必要組件缺失,Image 不應發布到 Production。 ║${NC}"
|
||||
echo -e "${RED}╚══════════════════════════════════════════════════════════════════════╝${NC}"
|
||||
exit 1
|
||||
elif [ $WARN -gt 0 ]; then
|
||||
echo -e "${YELLOW}╔══════════════════════════════════════════════════════════════════════╗${NC}"
|
||||
echo -e "${YELLOW}║ ⚠️ 離線驗證通過,但有警告 ║${NC}"
|
||||
echo -e "${YELLOW}║ 部分可選功能可能受限,請確認是否符合需求。 ║${NC}"
|
||||
echo -e "${YELLOW}╚══════════════════════════════════════════════════════════════════════╝${NC}"
|
||||
exit 0
|
||||
else
|
||||
echo -e "${GREEN}╔══════════════════════════════════════════════════════════════════════╗${NC}"
|
||||
echo -e "${GREEN}║ ✅ 離線驗證完全通過! ║${NC}"
|
||||
echo -e "${GREEN}║ 系統可在 docker run --network=none 環境正常運作。 ║${NC}"
|
||||
echo -e "${GREEN}║ (翻譯服務除外,需網路連接) ║${NC}"
|
||||
echo -e "${GREEN}╚══════════════════════════════════════════════════════════════════════╝${NC}"
|
||||
exit 0
|
||||
fi
|
||||
Loading…
Add table
Add a link
Reference in a new issue