From 1b8cae30a0f670eb93b071c99a5ded59f39ccd9a Mon Sep 17 00:00:00 2001 From: Your Name Date: Sat, 24 Jan 2026 15:47:04 +0800 Subject: [PATCH] =?UTF-8?q?feat:=20=E6=96=B0=E5=A2=9E=20Lite=20=E7=89=88?= =?UTF-8?q?=20v0.1.15-lite?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - Dockerfile.lite: 輕量版,僅保留英/簡/繁語言 - 移除 Inkscape/VIPS/ImageMagick 以減小體積 (< 1.5 GB) - docker-build-lite.yml: 自動觸發 Lite 版發布 - docker-build-remote.yml: 改進交互邏輯,支援 standard/full/lite 版本 - release.yml: 修正只觸發一般版發布 --- .github/workflows/docker-build-lite.yml | 346 ++++++++++++++++++++++ .github/workflows/docker-build-remote.yml | 253 +++++++++++++--- .github/workflows/release.yml | 8 +- Dockerfile.full | 47 +-- Dockerfile.lite | 335 +++++++++++++++++++++ README.md | 27 ++ docs/說明文件.md | 11 +- docs/部署指南/Docker-Lite.md | 244 +++++++++++++++ docs/部署指南/Docker.md | 32 +- 9 files changed, 1222 insertions(+), 81 deletions(-) create mode 100644 .github/workflows/docker-build-lite.yml create mode 100644 Dockerfile.lite create mode 100644 docs/部署指南/Docker-Lite.md diff --git a/.github/workflows/docker-build-lite.yml b/.github/workflows/docker-build-lite.yml new file mode 100644 index 0000000..4f6d0e7 --- /dev/null +++ b/.github/workflows/docker-build-lite.yml @@ -0,0 +1,346 @@ +# ============================================================ +# Docker Build & Push - Lite 版(自動觸發) +# ============================================================ +# 說明:當 Git tag 符合 vX.Y.Z-lite 格式時自動觸發 Lite 版 build +# 範例:v0.1.15-lite, v1.0.0-lite +# ============================================================ + +name: Docker Build Lite (Auto Tag) + +on: + push: + tags: + - "v*.*.*-lite" + +env: + # Docker Hub 映像庫 + DOCKER_IMAGE: convertx/convertx-cn + +concurrency: + group: ${{ github.workflow }}-${{ github.ref }} + cancel-in-progress: true + +jobs: + # ======================================== + # Build job - 為每個平台建構 Docker image + # ======================================== + build: + strategy: + fail-fast: false + matrix: + platform: + - linux/amd64 + - linux/arm64 + + permissions: + contents: write + packages: write + attestations: write + id-token: write + + runs-on: ${{ matrix.platform == 'linux/amd64' && 'ubuntu-24.04' || matrix.platform == 'linux/arm64' && 'ubuntu-24.04-arm' }} + + name: Build Lite image for ${{ matrix.platform }} + + steps: + - name: Prepare environment for current platform + id: prepare + run: | + platform=${{ matrix.platform }} + echo "PLATFORM_PAIR=${platform//\//-}" >> $GITHUB_ENV + + - name: Checkout repository + uses: actions/checkout@v4 + + # ======================================== + # 從 tag 提取版本號 + # ======================================== + - name: Extract version from tag + id: version + run: | + # 從 tag 中提取版本號(例如 v0.1.15-lite -> 0.1.15-lite) + TAG="${{ github.ref_name }}" + VERSION="${TAG#v}" + echo "VERSION=${VERSION}" >> $GITHUB_OUTPUT + echo "TAG=${TAG}" >> $GITHUB_OUTPUT + echo "📦 版本: ${VERSION}" + + # ======================================== + # 清理磁碟空間 + # ======================================== + - name: Free disk space (aggressive) + run: | + echo "🧹 Aggressive disk cleanup for Lite builds..." + echo "========================================" + echo "📊 初始磁碟空間:" + df -h / + echo "========================================" + + # 移除大型預裝軟體 + sudo rm -rf /usr/share/dotnet || true + sudo rm -rf /usr/local/lib/android || true + sudo rm -rf /opt/ghc || true + sudo rm -rf /opt/hostedtoolcache/CodeQL || true + sudo rm -rf /usr/local/share/boost || true + sudo rm -rf /usr/share/swift || true + sudo rm -rf /opt/hostedtoolcache || true + sudo rm -rf /usr/share/az_* || true + sudo rm -rf /opt/az || true + sudo rm -rf /usr/lib/google-cloud-sdk || true + sudo rm -rf /usr/local/share/powershell || true + sudo rm -rf /usr/share/miniconda || true + + # 清理系統 cache + sudo apt-get clean || true + sudo apt-get autoremove -y || true + sudo rm -rf /var/lib/apt/lists/* || true + + # 清理 Docker cache + docker system prune -af --volumes || true + sudo rm -rf /var/lib/docker/buildkit || true + + echo "========================================" + echo "📊 清理後磁碟空間:" + df -h / + echo "========================================" + + - name: downcase REPO + run: | + echo "REPO=${GITHUB_REPOSITORY@L}" >> "${GITHUB_ENV}" + + - name: Docker meta + id: meta + uses: docker/metadata-action@v5 + with: + images: | + ghcr.io/${{ env.REPO }} + ${{ env.DOCKER_IMAGE }} + tags: | + type=semver,pattern={{version}}-lite + type=raw,value=latest-lite,enable={{is_default_branch}} + + - name: Set up Docker Buildx + uses: docker/setup-buildx-action@v3 + with: + platforms: ${{ matrix.platform }} + driver-opts: | + image=moby/buildkit:latest + network=host + + - name: Login to GitHub Container Registry + uses: docker/login-action@v3 + with: + registry: ghcr.io + username: ${{ github.actor }} + password: ${{ secrets.GITHUB_TOKEN }} + + - name: Login to Docker Hub + uses: docker/login-action@v3 + with: + username: ${{ secrets.DOCKERHUB_USERNAME }} + password: ${{ secrets.DOCKERHUB_TOKEN }} + + # ======================================== + # Build Lite image + # ======================================== + - name: Build and push by digest + id: build + uses: docker/build-push-action@v6 + env: + DOCKER_BUILDKIT: 1 + with: + context: . + file: Dockerfile.lite + platforms: ${{ matrix.platform }} + labels: ${{ steps.meta.outputs.labels }} + annotations: ${{ steps.meta.outputs.annotations }} + outputs: type=image,name=ghcr.io/${{ env.REPO }},push-by-digest=true,name-canonical=true,oci-mediatypes=true,compression=zstd,compression-level=3 + push: true + cache-from: type=registry,ref=ghcr.io/${{ env.REPO }}:buildcache-lite-${{ env.PLATFORM_PAIR }} + cache-to: type=registry,ref=ghcr.io/${{ env.REPO }}:buildcache-lite-${{ env.PLATFORM_PAIR }},mode=max,compression=zstd + build-args: | + BUILDKIT_INLINE_CACHE=1 + + - name: Export digest + run: | + mkdir -p /tmp/digests + digest="${{ steps.build.outputs.digest }}" + touch "/tmp/digests/${digest#sha256:}" + + - name: Upload digest + uses: actions/upload-artifact@v4 + with: + name: digests-lite-${{ env.PLATFORM_PAIR }} + path: /tmp/digests/* + if-no-files-found: error + retention-days: 1 + + # ======================================== + # Merge job - 合併多架構 manifest + # ======================================== + merge: + name: Merge Lite Docker manifests + runs-on: ubuntu-latest + + permissions: + contents: write + packages: write + attestations: write + id-token: write + + needs: + - build + + steps: + - name: Download digests + uses: actions/download-artifact@v4 + with: + path: /tmp/digests + pattern: digests-lite-* + merge-multiple: true + + - name: Extract version from tag + id: version + run: | + TAG="${{ github.ref_name }}" + VERSION="${TAG#v}" + echo "VERSION=${VERSION}" >> $GITHUB_OUTPUT + echo "TAG=${TAG}" >> $GITHUB_OUTPUT + + - name: downcase REPO + run: | + echo "REPO=${GITHUB_REPOSITORY@L}" >> "${GITHUB_ENV}" + + - name: Docker meta + id: meta + uses: docker/metadata-action@v5 + with: + images: | + ghcr.io/${{ env.REPO }} + ${{ env.DOCKER_IMAGE }} + tags: | + type=raw,value=${{ steps.version.outputs.VERSION }} + type=raw,value=latest-lite + + - name: Set up Docker Buildx + uses: docker/setup-buildx-action@v3 + + - name: Login to GitHub Container Registry + uses: docker/login-action@v3 + with: + registry: ghcr.io + username: ${{ github.actor }} + password: ${{ secrets.GITHUB_TOKEN }} + + - name: Login to Docker Hub + uses: docker/login-action@v3 + with: + username: ${{ secrets.DOCKERHUB_USERNAME }} + password: ${{ secrets.DOCKERHUB_TOKEN }} + + - name: Get execution timestamp + id: timestamp + run: | + echo "timestamp=$(date -u +"%Y-%m-%dT%H:%M:%SZ")" >> $GITHUB_OUTPUT + + - name: Create manifest list and push + working-directory: /tmp/digests + run: | + docker buildx imagetools create \ + $(jq -cr '.tags | map("-t " + .) | join(" ")' <<< "$DOCKER_METADATA_OUTPUT_JSON") \ + --annotation='index:org.opencontainers.image.description=ConvertX-CN Lite - 輕量版檔案轉換服務' \ + --annotation='index:org.opencontainers.image.created=${{ steps.timestamp.outputs.timestamp }}' \ + --annotation='index:org.opencontainers.image.url=${{ github.event.repository.url }}' \ + --annotation='index:org.opencontainers.image.source=${{ github.event.repository.url }}' \ + $(printf 'ghcr.io/${{ env.REPO }}@sha256:%s ' *) + + - name: Inspect image + run: | + docker buildx imagetools inspect '${{ env.DOCKER_IMAGE }}:${{ steps.version.outputs.VERSION }}' + + # ======================================== + # 建立 GitHub Release + # ======================================== + - name: Checkout for changelog + uses: actions/checkout@v4 + with: + fetch-depth: 0 + + - name: Generate Changelog + id: changelog + run: | + echo "========================================" + echo "📝 生成 Changelog" + echo "========================================" + + # 取得前一個 tag + PREVIOUS_TAG=$(git describe --tags --abbrev=0 HEAD^ 2>/dev/null || echo "") + + if [ -z "$PREVIOUS_TAG" ]; then + echo "📋 無前一個 tag,取得所有 commits..." + CHANGELOG=$(git log --pretty=format:"- %s (%h)" HEAD) + else + echo "📋 取得 ${PREVIOUS_TAG} 到 HEAD 的 commits..." + CHANGELOG=$(git log --pretty=format:"- %s (%h)" ${PREVIOUS_TAG}..HEAD) + fi + + # 建立 changelog 檔案 + echo "## ConvertX-CN Lite 版本" > changelog.txt + echo "" >> changelog.txt + echo "這是 ConvertX-CN 的輕量版本,適合一般使用者與快速部署。" >> changelog.txt + echo "" >> changelog.txt + echo "### 變更記錄" >> changelog.txt + echo "" >> changelog.txt + echo "$CHANGELOG" >> changelog.txt + echo "" >> changelog.txt + echo "### 使用方式" >> changelog.txt + echo "" >> changelog.txt + echo "\`\`\`bash" >> changelog.txt + echo "docker pull ${{ env.DOCKER_IMAGE }}:${{ steps.version.outputs.VERSION }}" >> changelog.txt + echo "\`\`\`" >> changelog.txt + echo "" >> changelog.txt + echo "Full Changelog: https://github.com/${{ github.repository }}/compare/${PREVIOUS_TAG}...${{ steps.version.outputs.TAG }}" >> changelog.txt + + echo "" + echo "✅ Changelog 已生成" + cat changelog.txt + + - name: Create GitHub Release + uses: softprops/action-gh-release@v2 + with: + tag_name: ${{ steps.version.outputs.TAG }} + name: ${{ steps.version.outputs.TAG }} (Lite) + body_path: changelog.txt + draft: false + prerelease: false + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + + # ======================================== + # 完成摘要 + # ======================================== + - name: Build Summary + run: | + echo "========================================" + echo "✅ ConvertX-CN Lite Build 完成!" + echo "========================================" + echo "" + echo "🏷️ 版本: ${{ steps.version.outputs.VERSION }}" + echo "📦 版本類型: Lite 版(輕量版)" + echo "" + echo "📦 映像資訊:" + echo " - ${{ env.DOCKER_IMAGE }}:${{ steps.version.outputs.VERSION }}" + echo " - ${{ env.DOCKER_IMAGE }}:latest-lite" + echo " - ghcr.io/${{ env.REPO }}:${{ steps.version.outputs.VERSION }}" + echo "" + echo "🏗️ 支援的架構:" + echo " - linux/amd64" + echo " - linux/arm64" + echo "" + echo "📝 使用方式:" + echo " docker pull ${{ env.DOCKER_IMAGE }}:${{ steps.version.outputs.VERSION }}" + echo " docker pull ${{ env.DOCKER_IMAGE }}:latest-lite" + echo "" + echo "========================================" + echo "🎉 Lite 版本發布成功!" + echo "========================================" diff --git a/.github/workflows/docker-build-remote.yml b/.github/workflows/docker-build-remote.yml index fc63f40..bc81c28 100644 --- a/.github/workflows/docker-build-remote.yml +++ b/.github/workflows/docker-build-remote.yml @@ -8,14 +8,24 @@ name: Docker Build & Push (Remote Host via Tailscale) on: - # 手動觸發,支援輸入 image tag + # 手動觸發,支援輸入 image tag 與 build target workflow_dispatch: inputs: image_tag: - description: "Docker Image Tag(例如:0.1.12.test)" + description: "📦 版本號(例如:0.1.15、0.1.15-lite、0.1.15.test)" required: true - default: "0.1.12.test" + default: "" type: string + build_target: + description: "🎯 Build 目標版本(auto = 自動從版本號偵測)" + required: true + default: "auto" + type: choice + options: + - auto + - standard + - full + - lite # ============================================================ # 環境變數設定 @@ -41,6 +51,111 @@ jobs: runs-on: ubuntu-latest steps: + # ======================================== + # Step 0: 解析版本快捷選項 + # 說明:根據 version_preset 自動設定 IMAGE_TAG 和 BUILD_TARGET + # ======================================== + - name: 🔧 解析版本設定 + id: parse_version + run: | + echo "========================================" + echo "🔧 解析版本設定" + echo "========================================" + + INPUT_TAG="${{ github.event.inputs.image_tag }}" + BUILD_TARGET_INPUT="${{ github.event.inputs.build_target }}" + + echo "輸入參數:" + echo " image_tag: ${INPUT_TAG}" + echo " build_target: ${BUILD_TARGET_INPUT}" + echo "" + + # 驗證版本號不為空 + if [ -z "${INPUT_TAG}" ]; then + echo "❌ 錯誤:必須填寫版本號" + exit 1 + fi + + # ======================================== + # 判斷 build target(auto 時根據 tag 自動判斷) + # ======================================== + if [ "${BUILD_TARGET_INPUT}" = "auto" ]; then + if [[ "${INPUT_TAG}" == *"-lite"* ]]; then + FINAL_BUILD_TARGET="lite" + echo "🔍 自動偵測:版本號含 '-lite',選擇 Lite 版" + elif [[ "${INPUT_TAG}" == *"-full"* ]]; then + FINAL_BUILD_TARGET="full" + echo "🔍 自動偵測:版本號含 '-full',選擇 Full 版" + else + FINAL_BUILD_TARGET="standard" + echo "🔍 自動偵測:標準版本號,選擇一般版" + fi + else + FINAL_BUILD_TARGET="${BUILD_TARGET_INPUT}" + fi + + # ======================================== + # 根據 build target 決定最終 tag + # ======================================== + # 移除可能的後綴以獲取基礎版本號 + BASE_TAG="${INPUT_TAG%-lite}" + BASE_TAG="${BASE_TAG%-full}" + + case "${FINAL_BUILD_TARGET}" in + "lite") + FINAL_TAG="${BASE_TAG}-lite" + DOCKERFILE="Dockerfile.lite" + LATEST_TAG="latest-lite" + EDITION="Lite 版(輕量版)" + ;; + "full") + FINAL_TAG="${BASE_TAG}-full" + DOCKERFILE="Dockerfile.full" + LATEST_TAG="latest-full" + EDITION="Full 版(擴充版)" + ;; + *) + FINAL_TAG="${BASE_TAG}" + DOCKERFILE="Dockerfile" + LATEST_TAG="latest" + EDITION="一般版(標準版)" + ;; + esac + + # ======================================== + # 判斷是否為正式版本(決定是否更新 latest) + # 正式版本格式:純數字+點號(如 0.1.15、0.1.15.1) + # 測試版本格式:含有 test/dev/alpha/beta 或其他非數字字元 + # ======================================== + if [[ "${BASE_TAG}" =~ ^[0-9]+(\.[0-9]+)+$ ]]; then + IS_OFFICIAL="true" + echo "✅ 正式版本:將同時更新 ${LATEST_TAG}" + else + IS_OFFICIAL="false" + echo "⚠️ 測試版本:不更新 ${LATEST_TAG}" + fi + + echo "" + echo "========================================" + echo "📋 最終設定:" + echo "========================================" + echo " 版本號: ${FINAL_TAG}" + echo " Build 目標: ${FINAL_BUILD_TARGET}" + echo " Dockerfile: ${DOCKERFILE}" + echo " 版本類型: ${EDITION}" + echo " Latest Tag: ${LATEST_TAG}" + echo " 正式版本: ${IS_OFFICIAL}" + echo "========================================" + + # 輸出到 GITHUB_OUTPUT + echo "image_tag=${FINAL_TAG}" >> $GITHUB_OUTPUT + echo "base_tag=${BASE_TAG}" >> $GITHUB_OUTPUT + echo "build_target=${FINAL_BUILD_TARGET}" >> $GITHUB_OUTPUT + echo "dockerfile=${DOCKERFILE}" >> $GITHUB_OUTPUT + echo "latest_tag=${LATEST_TAG}" >> $GITHUB_OUTPUT + echo "edition=${EDITION}" >> $GITHUB_OUTPUT + echo "is_official=${IS_OFFICIAL}" >> $GITHUB_OUTPUT + # ======================================== # Step 1: Checkout repository # 說明:檢出程式碼(雖然 build 在遠端,但需要 workflow 完整性) @@ -300,22 +415,31 @@ jobs: # ======================================== # Step 10: Multi-Arch Docker Build # 說明:使用 buildx 同時建構 amd64 和 arm64 + # 支援 full/lite 版本選擇 # ======================================== - name: 🔨 Multi-Arch Docker Build run: | echo "========================================" echo "🔨 開始 Multi-Arch Docker Build" echo "========================================" - echo "版本: v${{ github.event.inputs.image_tag }}" - echo "映像名稱: ${{ env.DOCKER_IMAGE_REPO }}:${{ github.event.inputs.image_tag }}" - - # 判斷是否為正式版本(純數字+點號,支援任意段數如 0.1.10 或 0.1.10.1) - IMAGE_TAG="${{ github.event.inputs.image_tag }}" - if [[ "$IMAGE_TAG" =~ ^[0-9]+(\.[0-9]+)+$ ]]; then - echo "✅ 正式版本,將同時標記 latest" + + # 使用 parse_version 步驟的輸出 + FINAL_TAG="${{ steps.parse_version.outputs.image_tag }}" + DOCKERFILE="${{ steps.parse_version.outputs.dockerfile }}" + LATEST_TAG="${{ steps.parse_version.outputs.latest_tag }}" + IS_OFFICIAL="${{ steps.parse_version.outputs.is_official }}" + EDITION="${{ steps.parse_version.outputs.edition }}" + + echo "🔹 Build 目標: ${EDITION}" + echo "🔹 使用 Dockerfile: ${DOCKERFILE}" + echo "🔹 版本: v${FINAL_TAG}" + echo "🔹 映像名稱: ${{ env.DOCKER_IMAGE_REPO }}:${FINAL_TAG}" + + if [ "${IS_OFFICIAL}" = "true" ]; then + echo "✅ 正式版本,將同時標記 ${LATEST_TAG}" ADD_LATEST="true" else - echo "⚠️ 測試版本,不標記 latest" + echo "⚠️ 測試版本,不標記 ${LATEST_TAG}" ADD_LATEST="false" fi @@ -327,10 +451,11 @@ jobs: WORKDIR="${{ env.REMOTE_WORKDIR }}" PROJECT="${{ env.PROJECT_NAME }}" - IMAGE="${{ env.DOCKER_IMAGE_REPO }}:${{ github.event.inputs.image_tag }}" - IMAGE_LATEST="${{ env.DOCKER_IMAGE_REPO }}:latest" + IMAGE="${{ env.DOCKER_IMAGE_REPO }}:${FINAL_TAG}" + IMAGE_LATEST="${{ env.DOCKER_IMAGE_REPO }}:${LATEST_TAG}" BUILDER_NAME="multiarch-builder-${{ github.run_id }}" ADD_LATEST="${ADD_LATEST}" + DOCKERFILE="${DOCKERFILE}" echo "📂 進入專案目錄..." cd "\${WORKDIR}/\${PROJECT}" @@ -339,6 +464,7 @@ jobs: echo "" echo "🔨 執行 Multi-Arch Docker buildx..." echo "映像標籤: \${IMAGE}" + echo "Dockerfile: \${DOCKERFILE}" echo "目標平台: linux/amd64, linux/arm64" echo "" @@ -347,7 +473,7 @@ jobs: # 根據版本類型決定是否加入 latest tag if [ "\${ADD_LATEST}" = "true" ]; then - echo "📌 同時標記 latest" + echo "📌 同時標記 \${IMAGE_LATEST}" BUILD_TAGS="-t \${IMAGE} -t \${IMAGE_LATEST}" else echo "📌 僅標記版本號(測試版本)" @@ -355,10 +481,11 @@ jobs: fi # Multi-arch build(只建構,不推送) - if ! docker buildx build \ - --platform linux/amd64,linux/arm64 \ - \${BUILD_TAGS} \ - --progress=plain \ + if ! docker buildx build \\ + --platform linux/amd64,linux/arm64 \\ + -f \${DOCKERFILE} \\ + \${BUILD_TAGS} \\ + --progress=plain \\ . 2>&1; then echo "" @@ -394,22 +521,30 @@ jobs: # ======================================== # Step 11: Docker Push 到 Docker Hub # 說明:推送建構好的映像到 Docker Hub + # 支援 standard/full/lite 版本選擇 # ======================================== - name: 📤 Docker Push 到 Docker Hub run: | echo "========================================" echo "📤 推送映像到 Docker Hub" echo "========================================" - echo "版本: v${{ github.event.inputs.image_tag }}" - echo "映像: ${{ env.DOCKER_IMAGE_REPO }}:${{ github.event.inputs.image_tag }}" - - # 判斷是否為正式版本(純數字+點號,支援任意段數如 0.1.10 或 0.1.10.1) - IMAGE_TAG="${{ github.event.inputs.image_tag }}" - if [[ "$IMAGE_TAG" =~ ^[0-9]+(\.[0-9]+)+$ ]]; then - echo "✅ 正式版本,將同時推送 latest" + + # 使用 parse_version 步驟的輸出 + FINAL_TAG="${{ steps.parse_version.outputs.image_tag }}" + DOCKERFILE="${{ steps.parse_version.outputs.dockerfile }}" + LATEST_TAG="${{ steps.parse_version.outputs.latest_tag }}" + IS_OFFICIAL="${{ steps.parse_version.outputs.is_official }}" + EDITION="${{ steps.parse_version.outputs.edition }}" + + echo "🔹 Push 目標: ${EDITION}" + echo "🔹 版本: v${FINAL_TAG}" + echo "🔹 映像: ${{ env.DOCKER_IMAGE_REPO }}:${FINAL_TAG}" + + if [ "${IS_OFFICIAL}" = "true" ]; then + echo "✅ 正式版本,將同時推送 ${LATEST_TAG}" ADD_LATEST="true" else - echo "⚠️ 測試版本,不推送 latest" + echo "⚠️ 測試版本,不推送 ${LATEST_TAG}" ADD_LATEST="false" fi echo "" @@ -431,10 +566,11 @@ jobs: WORKDIR="${{ env.REMOTE_WORKDIR }}" PROJECT="${{ env.PROJECT_NAME }}" - IMAGE="${{ env.DOCKER_IMAGE_REPO }}:${{ github.event.inputs.image_tag }}" - IMAGE_LATEST="${{ env.DOCKER_IMAGE_REPO }}:latest" + IMAGE="${{ env.DOCKER_IMAGE_REPO }}:${FINAL_TAG}" + IMAGE_LATEST="${{ env.DOCKER_IMAGE_REPO }}:${LATEST_TAG}" BUILDER_NAME="multiarch-builder-${{ github.run_id }}" ADD_LATEST="${ADD_LATEST}" + DOCKERFILE="${DOCKERFILE}" echo "📂 進入專案目錄..." cd "\${WORKDIR}/\${PROJECT}" @@ -442,6 +578,7 @@ jobs: echo "" echo "📤 執行 Docker Push..." echo "映像標籤: \${IMAGE}" + echo "Dockerfile: \${DOCKERFILE}" # 確保使用正確的 builder docker buildx use "\${BUILDER_NAME}" @@ -451,7 +588,7 @@ jobs: echo "同時推送: \${IMAGE_LATEST}" BUILD_TAGS="-t \${IMAGE} -t \${IMAGE_LATEST}" else - echo "(測試版本,不推送 latest)" + echo "(測試版本,不推送 ${LATEST_TAG})" BUILD_TAGS="-t \${IMAGE}" fi echo "" @@ -459,6 +596,7 @@ jobs: # 使用 buildx build --push 來推送 multi-arch 映像 if ! docker buildx build \ --platform linux/amd64,linux/arm64 \ + -f \${DOCKERFILE} \ \${BUILD_TAGS} \ --push \ --progress=plain \ @@ -496,25 +634,31 @@ jobs: # ======================================== # Step 13: 驗證 Docker Hub 映像 # 說明:確認映像已成功推送並檢查架構 + # 支援 standard/full/lite 版本 # ======================================== - name: ✅ 驗證 Docker Hub 映像 run: | echo "========================================" echo "✅ 驗證 Docker Hub 映像" echo "========================================" - echo "版本: v${{ github.event.inputs.image_tag }}" - echo "映像: ${{ env.DOCKER_IMAGE_REPO }}:${{ github.event.inputs.image_tag }}" + + FINAL_TAG="${{ steps.parse_version.outputs.image_tag }}" + EDITION="${{ steps.parse_version.outputs.edition }}" + + echo "🔹 版本類型: ${EDITION}" + echo "🔹 版本: v${FINAL_TAG}" + echo "🔹 映像: ${{ env.DOCKER_IMAGE_REPO }}:${FINAL_TAG}" echo "" - tailscale ssh ${{ secrets.SSH_USER }}@${{ secrets.SSH_HOST }} << 'REMOTE_EOF' + tailscale ssh ${{ secrets.SSH_USER }}@${{ secrets.SSH_HOST }} << REMOTE_EOF set -e - IMAGE="${{ env.DOCKER_IMAGE_REPO }}:${{ github.event.inputs.image_tag }}" + IMAGE="${{ env.DOCKER_IMAGE_REPO }}:${FINAL_TAG}" echo "📋 檢查映像 manifest(顯示支援的架構)..." echo "" - docker buildx imagetools inspect "${IMAGE}" + docker buildx imagetools inspect "\${IMAGE}" echo "" echo "✅ 映像驗證完成" @@ -585,6 +729,7 @@ jobs: # ======================================== # Step 16: 顯示完成摘要 # 說明:顯示本次 build 的摘要資訊 + # 支援 standard/full/lite 版本 # ======================================== - name: 📋 Build 完成摘要 run: | @@ -592,15 +737,24 @@ jobs: echo "✅ Multi-Arch Docker Build & Push 完成!" echo "========================================" echo "" - echo "🏷️ 版本: v${{ github.event.inputs.image_tag }}" + + # 使用 parse_version 步驟的輸出 + FINAL_TAG="${{ steps.parse_version.outputs.image_tag }}" + BASE_TAG="${{ steps.parse_version.outputs.base_tag }}" + DOCKERFILE="${{ steps.parse_version.outputs.dockerfile }}" + LATEST_TAG="${{ steps.parse_version.outputs.latest_tag }}" + IS_OFFICIAL="${{ steps.parse_version.outputs.is_official }}" + EDITION="${{ steps.parse_version.outputs.edition }}" + + echo "🏷️ 版本: v${FINAL_TAG}" + echo "📦 版本類型: ${EDITION}" echo "" echo "📦 映像資訊:" - echo " - 版本標籤: ${{ env.DOCKER_IMAGE_REPO }}:${{ github.event.inputs.image_tag }}" + echo " - 版本標籤: ${{ env.DOCKER_IMAGE_REPO }}:${FINAL_TAG}" - # 判斷是否為正式版本(純數字+點號) - IMAGE_TAG="${{ github.event.inputs.image_tag }}" - if [[ "$IMAGE_TAG" =~ ^[0-9]+(\.[0-9]+)+$ ]]; then - echo " - Latest 標籤: ${{ env.DOCKER_IMAGE_REPO }}:latest ✅" + # 判斷是否為正式版本 + if [ "${IS_OFFICIAL}" = "true" ]; then + echo " - Latest 標籤: ${{ env.DOCKER_IMAGE_REPO }}:${LATEST_TAG} ✅" else echo " - Latest 標籤: (測試版本,未更新)" fi @@ -615,11 +769,12 @@ jobs: echo " - 遠端主機: ${{ secrets.SSH_HOST }}" echo " - 工作目錄: ${{ env.REMOTE_WORKDIR }}" echo " - 專案名稱: ${{ env.PROJECT_NAME }}" + echo " - Dockerfile: ${DOCKERFILE}" echo "" echo "📝 使用方式:" - echo " docker pull ${{ env.DOCKER_IMAGE_REPO }}:${{ github.event.inputs.image_tag }}" - if [[ "$IMAGE_TAG" =~ ^[0-9]+(\.[0-9]+)+$ ]]; then - echo " docker pull ${{ env.DOCKER_IMAGE_REPO }}:latest" + echo " docker pull ${{ env.DOCKER_IMAGE_REPO }}:${FINAL_TAG}" + if [ "${IS_OFFICIAL}" = "true" ]; then + echo " docker pull ${{ env.DOCKER_IMAGE_REPO }}:${LATEST_TAG}" fi echo "" echo "========================================" @@ -631,7 +786,7 @@ jobs: # 說明:從 git log 生成變更記錄(與 release.yml 邏輯一致) # ======================================== - name: 📝 Generate Changelog - if: ${{ !contains(github.event.inputs.image_tag, 'test') && !contains(github.event.inputs.image_tag, 'dev') && !contains(github.event.inputs.image_tag, 'alpha') && !contains(github.event.inputs.image_tag, 'beta') }} + if: ${{ !contains(steps.parse_version.outputs.image_tag, 'test') && !contains(steps.parse_version.outputs.image_tag, 'dev') && !contains(steps.parse_version.outputs.image_tag, 'alpha') && !contains(steps.parse_version.outputs.image_tag, 'beta') }} id: changelog run: | echo "========================================" @@ -671,12 +826,12 @@ jobs: # 注意:如果 Release 已存在會失敗,使用 continue-on-error 跳過 # ======================================== - name: 📦 Create GitHub Release - if: ${{ !contains(github.event.inputs.image_tag, 'test') && !contains(github.event.inputs.image_tag, 'dev') && !contains(github.event.inputs.image_tag, 'alpha') && !contains(github.event.inputs.image_tag, 'beta') }} + if: ${{ !contains(steps.parse_version.outputs.image_tag, 'test') && !contains(steps.parse_version.outputs.image_tag, 'dev') && !contains(steps.parse_version.outputs.image_tag, 'alpha') && !contains(steps.parse_version.outputs.image_tag, 'beta') }} continue-on-error: true uses: softprops/action-gh-release@v2 with: - tag_name: v${{ github.event.inputs.image_tag }} - name: v${{ github.event.inputs.image_tag }} + tag_name: v${{ steps.parse_version.outputs.image_tag }} + name: v${{ steps.parse_version.outputs.image_tag }} body_path: changelog.txt draft: false prerelease: false @@ -692,13 +847,13 @@ jobs: echo "========================================" echo "🔄 更新遠端 ConvertX-CN 服務" echo "========================================" - echo "版本: v${{ github.event.inputs.image_tag }}" + echo "版本: v${{ steps.parse_version.outputs.image_tag }}" echo "" tailscale ssh ${{ secrets.SSH_USER }}@${{ secrets.SSH_HOST }} << REMOTE_EOF set -e - IMAGE_TAG="v${{ github.event.inputs.image_tag }}" + IMAGE_TAG="v${{ steps.parse_version.outputs.image_tag }}" # 1. 進入專案資料夾 cd /home/bioailab/miniconda3/lid/app/convertx-cn diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 1696028..520e659 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -1,14 +1,16 @@ -name: Release +name: Release (一般版) on: push: tags: - - "v*.*.*" + # 只匹配一般版 tag(不含 -lite) + - "v[0-9]*.[0-9]*.[0-9]*" + - "!v*-lite" # 允許手動觸發 workflow_dispatch: inputs: tag: - description: "Tag to release (e.g., v0.1.13)" + description: "Tag to release (e.g., v0.1.15) - 一般版" required: true type: string diff --git a/Dockerfile.full b/Dockerfile.full index e6ef6a9..abf4668 100644 --- a/Dockerfile.full +++ b/Dockerfile.full @@ -1,25 +1,31 @@ # ============================================================================== # ConvertX-CN Full 擴充版 Dockerfile -# 版本:v0.1.6 +# 版本:v0.1.15 # ============================================================================== # -# ⚠️ 重要說明: -# 此 Dockerfile 必須基於 ConvertX-CN 官方 Image -# 用途:為進階使用者提供擴充功能的範本 +# 📦 Image 說明: +# - 基於 ConvertX-CN 官方 Image(一般版)進行擴充 +# - 適合需要更多語言 OCR 或完整 TexLive 的進階使用者 +# - ⚠️ 體積較大(可能超過 10GB) +# +# 🎯 適用場景: +# - 需要 65 種 OCR 語言全支援 +# - 需要完整 TexLive(特殊 LaTeX 套件) +# - 多語言企業環境 # # 📦 使用方式: # 1. 確保已有 convertx/convertx-cn:latest 或自行 build # 2. 取消註解需要的功能區塊 # 3. 執行:docker build -f Dockerfile.full -t convertx-cn-full . # -# ⚠️ 風險提示: +# ⚠️ 風險提示: # - 每個擴充功能都會增加 Image 大小 -# - 全部啟用可能使 Image 超過 10GB +# - 全部啟用可能使 Image 超過 15GB # - 請依實際需求選擇性啟用 # # ============================================================================== -# 基於 ConvertX-CN 官方 Image +# 基於 ConvertX-CN 官方 Image(一般版) FROM convertx/convertx-cn:latest # ============================================================================== @@ -27,6 +33,7 @@ FROM convertx/convertx-cn:latest # ============================================================================== # 說明:完整 LaTeX 支援,適合需要特殊 LaTeX 套件的使用者 # 風險:Image 體積大幅增加 +# ℹ️ 一般版已內建:texlive-base, texlive-latex-base, texlive-xetex, texlive-lang-cjk # ------------------------------------------------------------------------------ # RUN apt-get update && apt-get install -y --no-install-recommends \ # texlive-full \ @@ -41,6 +48,7 @@ FROM convertx/convertx-cn:latest # - 全部語言:約 +2GB # # 💡 建議:僅安裝實際需要的語言 +# ℹ️ 一般版已內建:eng, chi-tra, chi-sim, jpn, kor, deu, fra # ------------------------------------------------------------------------------ # --- 歐洲語言(西歐)--- @@ -203,23 +211,15 @@ FROM convertx/convertx-cn:latest # ============================================================================== # 🔧 進階轉換工具 # ============================================================================== - -# --- OpenCV(電腦視覺相關轉換)--- -# 約 +200MB -# RUN apt-get update && apt-get install -y --no-install-recommends \ -# python3-opencv \ -# && apt-get clean && rm -rf /var/lib/apt/lists/* - -# --- 額外影片編解碼器 --- -# 約 +50MB -# RUN apt-get update && apt-get install -y --no-install-recommends \ -# libavcodec-extra \ -# && apt-get clean && rm -rf /var/lib/apt/lists/* +# ℹ️ 一般版已內建:OpenCV, libavcodec-extra +# 以下工具在一般版中已包含,無需額外安裝 +# ------------------------------------------------------------------------------ # ============================================================================== # 🌐 額外 Locale 設定 # ============================================================================== # 如需更多語言的 locale 支援,取消以下註解 +# ℹ️ 一般版已內建:en_US, zh_TW, zh_CN, ja_JP, ko_KR, de_DE, fr_FR # ------------------------------------------------------------------------------ # RUN sed -i 's/# es_ES.UTF-8 UTF-8/es_ES.UTF-8 UTF-8/' /etc/locale.gen && \ # sed -i 's/# it_IT.UTF-8 UTF-8/it_IT.UTF-8 UTF-8/' /etc/locale.gen && \ @@ -234,6 +234,15 @@ FROM convertx/convertx-cn:latest # 📋 擴充功能總覽 # ============================================================================== # +# ℹ️ 一般版已內建功能: +# - 核心轉換:LibreOffice, FFmpeg, ImageMagick, Pandoc, Inkscape +# - OCR:Tesseract(7 種語言) +# - PDF 翻譯:PDFMathTranslate, BabelDOC +# - PDF 轉 MD:MinerU +# - 字型:Noto CJK, Liberation, 標楷體 +# - TexLive:基礎 + CJK + 德法 +# - OpenCV, libavcodec-extra +# # | 功能 | 預估大小 | 風險等級 | # |-------------------------|----------|----------| # | 完整 TexLive | +3GB | 高 | diff --git a/Dockerfile.lite b/Dockerfile.lite new file mode 100644 index 0000000..01ca40a --- /dev/null +++ b/Dockerfile.lite @@ -0,0 +1,335 @@ +# ============================================================================== +# ConvertX-CN Lite 版 Docker Image +# 版本:v0.1.15-lite +# ============================================================================== +# +# 📦 Image 說明: +# - ConvertX-CN 輕量版,適合一般使用者與快速部署 +# - 體積顯著小於一般版(目標 < 1.5 GB vs 8-12 GB) +# - 保留日常最常用的轉檔功能,移除 AI/OCR/翻譯等進階功能 +# - ⚠️ 無 AI 模型、無 OCR、無 PDF 翻譯功能 +# +# 🎯 適用場景: +# - 個人/小型團隊的基本轉檔需求 +# - 資源受限的環境(如 VPS、NAS、樹莓派) +# - 不需要 OCR/AI/翻譯功能的使用者 +# +# ✅ Lite 版包含功能(日常最常用): +# - LibreOffice(文件轉檔:DOC/DOCX/XLS/PPT → PDF) +# - GraphicsMagick(圖片轉檔:PNG/JPG/GIF/WEBP) +# - FFmpeg(影音轉檔:MP4/MP3/AVI/MKV) +# - Pandoc(文件格式:Markdown/HTML/DOCX) +# - Ghostscript + qpdf(PDF 處理) +# - PDF 數位簽章(PFX/PKCS#12) +# - 精簡版 UI(僅英文、簡體中文、繁體中文) +# +# ❌ Lite 版不包含: +# - PDFMathTranslate / BabelDOC(PDF 翻譯) +# - MinerU(PDF 轉 Markdown) +# - OCR / Tesseract +# - AI 模型 / VLM / YOLO +# - Calibre(電子書轉換) +# - ImageMagick / Inkscape / VIPS +# - CAD / 3D / assimp +# - TexLive(LaTeX) +# +# 📊 Image 大小:目標 < 1.5 GB +# +# ============================================================================== + +FROM debian:bookworm-slim AS base +LABEL org.opencontainers.image.source="https://github.com/pi-docket/ConvertX-CN" +LABEL org.opencontainers.image.description="ConvertX-CN Lite - 輕量版檔案轉換服務" +LABEL org.opencontainers.image.version="lite" +WORKDIR /app + +# 配置 APT 重試機制(解決 Multi-Arch Build 時的網路不穩定問題) +RUN echo 'Acquire::Retries "5";' > /etc/apt/apt.conf.d/80-retries \ + && echo 'Acquire::http::Timeout "120";' >> /etc/apt/apt.conf.d/80-retries \ + && echo 'Acquire::https::Timeout "120";' >> /etc/apt/apt.conf.d/80-retries \ + && echo 'Acquire::ftp::Timeout "120";' >> /etc/apt/apt.conf.d/80-retries \ + && echo 'DPkg::Lock::Timeout "120";' >> /etc/apt/apt.conf.d/80-retries + +# install bun +RUN apt-get update && apt-get install -y --no-install-recommends \ + curl \ + unzip \ + ca-certificates \ + && rm -rf /var/lib/apt/lists/* + +# if architecture is arm64, use the arm64 version of bun +RUN ARCH=$(uname -m) && \ + if [ "$ARCH" = "aarch64" ]; then \ + curl -fsSL -o bun-linux-aarch64.zip https://github.com/oven-sh/bun/releases/download/bun-v1.3.6/bun-linux-aarch64.zip; \ + else \ + curl -fsSL -o bun-linux-x64-baseline.zip https://github.com/oven-sh/bun/releases/download/bun-v1.3.6/bun-linux-x64-baseline.zip; \ + fi + +RUN unzip -j bun-linux-*.zip -d /usr/local/bin && \ + rm bun-linux-*.zip && \ + chmod +x /usr/local/bin/bun + +# install dependencies into temp directory +# this will cache them and speed up future builds +FROM base AS install +RUN mkdir -p /temp/dev +COPY package.json bun.lock /temp/dev/ +RUN cd /temp/dev && bun install --frozen-lockfile + +# install with --production (exclude devDependencies) +RUN mkdir -p /temp/prod +COPY package.json bun.lock /temp/prod/ +RUN cd /temp/prod && bun install --frozen-lockfile --production + +FROM base AS prerelease +WORKDIR /app +COPY --from=install /temp/dev/node_modules node_modules +COPY . . + +# ENV NODE_ENV=production +RUN bun run build + +# ============================================================================== +# Release Stage - Lite 版本 +# ============================================================================== +FROM base AS release + +# ============================================================================== +# 依賴安裝(Lite 版 - 極簡安裝) +# ============================================================================== +# +# ✅ 保留工具(日常最常用): +# - LibreOffice(文件轉檔 - 最重要) +# - GraphicsMagick(圖片轉檔 - 輕量替代 ImageMagick) +# - FFmpeg(影音轉檔) +# - Pandoc(Markdown/HTML/DOCX 轉換) +# - Ghostscript + qpdf(PDF 處理) +# - poppler-utils(PDF 工具) +# - potrace(點陣圖轉向量) +# +# ❌ 移除工具(減少體積): +# - Tesseract / OCR(約 +200MB) +# - Calibre(約 +500MB) +# - TexLive(約 +1GB) +# - ImageMagick(用 GraphicsMagick 替代) +# - Inkscape(約 +300MB) +# - VIPS(約 +100MB) +# - Python AI 套件 +# - assimp / CAD 工具 +# +# ============================================================================== + +# 配置 APT 重試機制 +RUN echo 'Acquire::Retries "5";' > /etc/apt/apt.conf.d/80-retries \ + && echo 'Acquire::http::Timeout "120";' >> /etc/apt/apt.conf.d/80-retries \ + && echo 'Acquire::https::Timeout "120";' >> /etc/apt/apt.conf.d/80-retries \ + && echo 'Acquire::ftp::Timeout "120";' >> /etc/apt/apt.conf.d/80-retries \ + && echo 'APT::Get::Assume-Yes "true";' >> /etc/apt/apt.conf.d/80-retries \ + && echo 'DPkg::Lock::Timeout "120";' >> /etc/apt/apt.conf.d/80-retries + +# 階段 1:基礎系統工具 +RUN echo "" && \ + echo "========================================" && \ + echo "📦 階段 1/7:安裝基礎系統工具" && \ + echo "========================================" && \ + apt-get update --fix-missing && apt-get install -y --no-install-recommends \ + locales \ + ca-certificates \ + curl \ + openssl \ + && rm -rf /var/lib/apt/lists/* && \ + echo "✅ 階段 1/7 完成:基礎系統工具已安裝" + +# 階段 2:核心轉換工具 +RUN echo "" && \ + echo "========================================" && \ + echo "📦 階段 2/6:安裝核心轉換工具" && \ + echo "========================================" && \ + apt-get update --fix-missing && apt-get install -y --no-install-recommends \ + ghostscript \ + graphicsmagick \ + poppler-utils \ + potrace \ + qpdf \ + && rm -rf /var/lib/apt/lists/* && \ + echo "✅ 階段 2/6 完成:核心轉換工具已安裝" + +# 階段 2.1:安裝 dasel(從 GitHub 下載二進位檔案) +RUN echo "" && \ + echo " 🔧 階段 2.1:安裝 dasel..." && \ + ARCH=$(uname -m) && \ + if [ "$ARCH" = "aarch64" ]; then \ + DASEL_ARCH="linux_arm64"; \ + else \ + DASEL_ARCH="linux_amd64"; \ + fi && \ + curl -sSLf "https://github.com/TomWright/dasel/releases/download/v2.8.1/dasel_${DASEL_ARCH}" -o /usr/local/bin/dasel && \ + chmod +x /usr/local/bin/dasel && \ + echo " ✅ dasel 安裝完成" + +# 階段 2.2:安裝 resvg(從 GitHub 下載二進位檔案) +RUN echo "" && \ + echo " 🔧 階段 2.2:安裝 resvg..." && \ + ARCH=$(uname -m) && \ + if [ "$ARCH" = "aarch64" ]; then \ + echo " ⚠️ resvg 沒有 ARM64 預編譯版本,跳過安裝"; \ + else \ + curl -sSLf "https://github.com/linebender/resvg/releases/download/v0.44.0/resvg-linux-x86_64.tar.gz" -o /tmp/resvg.tar.gz && \ + tar -xzf /tmp/resvg.tar.gz -C /tmp/ && \ + mv /tmp/resvg /usr/local/bin/resvg && \ + chmod +x /usr/local/bin/resvg && \ + rm -rf /tmp/resvg.tar.gz && \ + echo " ✅ resvg 安裝完成"; \ + fi + +# 階段 3:影音處理工具(FFmpeg 精簡版) +RUN echo "" && \ + echo "========================================" && \ + echo "📦 階段 3/7:安裝影音處理工具(精簡版)" && \ + echo "========================================" && \ + apt-get update --fix-missing && apt-get install -y --no-install-recommends \ + ffmpeg \ + && rm -rf /var/lib/apt/lists/* && \ + echo "✅ 階段 3/7 完成:FFmpeg 已安裝" + +# 階段 4:Headless 支援(LibreOffice 需要) +# 注意:Lite 版移除 Inkscape 和 VIPS 以減少體積 +# GraphicsMagick 已在階段 2 安裝 +RUN echo "" && \ + echo "========================================" && \ + echo "📦 階段 4/6:安裝 Headless 支援" && \ + echo "========================================" && \ + apt-get update --fix-missing && apt-get install -y --no-install-recommends \ + xauth \ + xvfb \ + && rm -rf /var/lib/apt/lists/* && \ + echo "✅ 階段 4/6 完成:Headless 支援已安裝" + +# 階段 5:文件處理工具(Pandoc) +RUN echo "" && \ + echo "========================================" && \ + echo "📦 階段 5/6:安裝文件處理工具" && \ + echo "========================================" && \ + apt-get update --fix-missing && apt-get install -y --no-install-recommends \ + libemail-outlook-message-perl \ + pandoc \ + && rm -rf /var/lib/apt/lists/* && \ + echo "✅ 階段 5/6 完成:Pandoc 已安裝" + +# 階段 6:LibreOffice(核心文件轉檔引擎 + 基本字型) +# 使用完整 libreoffice 以確保所有轉檔功能正常 +RUN echo "" && \ + echo "========================================" && \ + echo "📦 階段 6/6:安裝 LibreOffice + 字型" && \ + echo "========================================" && \ + apt-get update --fix-missing && apt-get install -y --no-install-recommends \ + libreoffice \ + fonts-noto-cjk \ + fonts-liberation \ + && rm -rf /var/lib/apt/lists/* && \ + echo "✅ 階段 6/6 完成:LibreOffice + 字型已安裝" + +# ============================================================================== +# ✅ APT 套件安裝完成 +# ============================================================================== + +# ============================================================================== +# 🔐 PDF Packager 預設簽章憑證 + Python(合併以減少 layer) +# ============================================================================== +ENV PATH="/root/.local/bin:${PATH}" +ENV PIP_NO_CACHE_DIR=1 +ENV PDF_SIGN_P12_PATH="/app/certs/default.p12" +ENV PDF_SIGN_P12_PASSWORD="" +ENV PDF_SIGN_REASON="ConvertX-CN Lite PDF Packager" +ENV PDF_SIGN_LOCATION="Taiwan" +ENV PDF_SIGN_CONTACT="convertx-cn@localhost" + +RUN echo "" && \ + echo "========================================" && \ + echo "🔐 安裝 Python + 產生簽章憑證" && \ + echo "========================================" && \ + apt-get update --fix-missing && apt-get install -y --no-install-recommends \ + python3 \ + python3-pip \ + && rm -rf /var/lib/apt/lists/* && \ + pip3 install --no-cache-dir --break-system-packages endesive && \ + mkdir -p /app/certs && \ + openssl req -x509 -newkey rsa:2048 \ + -keyout /tmp/key.pem -out /tmp/cert.pem \ + -days 3650 -nodes \ + -subj "/CN=PDF Packager Default/O=ConvertX-CN Lite/C=TW" && \ + openssl pkcs12 -export \ + -inkey /tmp/key.pem -in /tmp/cert.pem \ + -out /app/certs/default.p12 \ + -passout pass: && \ + rm -f /tmp/key.pem /tmp/cert.pem && \ + chmod 644 /app/certs/default.p12 && \ + echo "✅ Python + PDF 簽章已安裝" + +# ============================================================================== +# 最終清理 + Locale 設定 + 自訂字型(合併以減少 layer) +# ============================================================================== +RUN rm -rf /usr/share/doc/* \ + && rm -rf /usr/share/man/* \ + && rm -rf /usr/share/info/* \ + && sed -i 's/# en_US.UTF-8 UTF-8/en_US.UTF-8 UTF-8/' /etc/locale.gen \ + && sed -i 's/# zh_TW.UTF-8 UTF-8/zh_TW.UTF-8 UTF-8/' /etc/locale.gen \ + && sed -i 's/# zh_CN.UTF-8 UTF-8/zh_CN.UTF-8 UTF-8/' /etc/locale.gen \ + && locale-gen + +# 安裝自訂字型(標楷體等台灣常用字型) +RUN mkdir -p /usr/share/fonts/truetype/custom +COPY fonts/ /usr/share/fonts/truetype/custom/ +RUN fc-cache -fv + +# ============================================================================== +# Install VTracer binary(向量追蹤工具) +# ============================================================================== +RUN ARCH=$(uname -m) && \ + if [ "$ARCH" = "aarch64" ]; then \ + VTRACER_ASSET="vtracer-aarch64-unknown-linux-musl.tar.gz"; \ + else \ + VTRACER_ASSET="vtracer-x86_64-unknown-linux-musl.tar.gz"; \ + fi && \ + curl -L -o /tmp/vtracer.tar.gz "https://github.com/visioncortex/vtracer/releases/download/0.6.4/${VTRACER_ASSET}" && \ + tar -xzf /tmp/vtracer.tar.gz -C /tmp/ && \ + mv /tmp/vtracer /usr/local/bin/vtracer && \ + chmod +x /usr/local/bin/vtracer && \ + rm /tmp/vtracer.tar.gz + +COPY --from=install /temp/prod/node_modules node_modules +COPY --from=prerelease /app/public/ /app/public/ +COPY --from=prerelease /app/dist /app/dist + +RUN mkdir data + +EXPOSE 3000/tcp + +# ============================================================================== +# 🔧 環境變數總覽(Lite 版) +# ============================================================================== + +# ------------------------------------------------------------------------------ +# 1️⃣ 系統 Locale(支援中文避免亂碼) +# ------------------------------------------------------------------------------ +ENV LANG=zh_TW.UTF-8 +ENV LC_ALL=zh_TW.UTF-8 + +# ------------------------------------------------------------------------------ +# 2️⃣ Headless 環境設定 +# ------------------------------------------------------------------------------ +ENV QT_QPA_PLATFORM="offscreen" +ENV DISPLAY=":99" + +# ------------------------------------------------------------------------------ +# 3️⃣ 應用程式設定 +# ------------------------------------------------------------------------------ +ENV PANDOC_PDF_ENGINE=pdflatex +ENV NODE_ENV=production + +# ------------------------------------------------------------------------------ +# 4️⃣ Lite 版標識 +# ------------------------------------------------------------------------------ +ENV CONVERTX_EDITION="lite" + +ENTRYPOINT [ "bun", "run", "dist/src/index.js" ] diff --git a/README.md b/README.md index 4119e41..63566ad 100644 --- a/README.md +++ b/README.md @@ -149,6 +149,33 @@ docker compose up -d --- +## 🎯 版本選擇:Full vs Lite + +ConvertX-CN 提供兩個版本,滿足不同需求: + +| 特性 | Full 版 | Lite 版 | +|------|---------|---------| +| **Image 大小** | 約 8-12 GB | 約 1.5-2.5 GB | +| **部署速度** | 較慢 | 快速 | +| **適用對象** | 進階使用者 | 一般使用者 | +| **OCR/AI/翻譯** | ✅ | ❌ | +| **基本轉檔** | ✅ | ✅ | + +### Lite 版快速啟動 + +```bash +docker run -d \ + --name convertx-cn-lite \ + -p 3000:3000 \ + -v ./data:/app/data \ + -e JWT_SECRET=你的隨機字串至少32字元 \ + convertx/convertx-cn:latest-lite +``` + +> 📖 詳細說明請參閱 [Lite 版部署指南](docs/部署指南/Docker-Lite.md) + +--- + ## 📄 License Overview **This is a Mixed License / Source-Available Project.** diff --git a/docs/說明文件.md b/docs/說明文件.md index f3751c0..1f9fde9 100644 --- a/docs/說明文件.md +++ b/docs/說明文件.md @@ -35,11 +35,12 @@ ### 部署 -| 文件 | 說明 | -| ------------------------------------- | --------------------------- | -| [Docker 部署](部署指南/Docker部署.md) | Docker Run & Docker Compose | -| [反向代理](部署指南/反向代理.md) | Nginx / Traefik / Caddy | -| [範例配置](範例配置/說明文件.md) | 可直接使用的配置檔 | +| 文件 | 說明 | +| -------------------------------------- | --------------------------- | +| [Docker 部署](部署指南/Docker.md) | Docker Run & Docker Compose | +| [Lite 版部署](部署指南/Docker-Lite.md) | 輕量版(較小 Image) | +| [反向代理](部署指南/反向代理.md) | Nginx / Traefik / Caddy | +| [範例配置](範例配置/說明文件.md) | 可直接使用的配置檔 | ### 配置 diff --git a/docs/部署指南/Docker-Lite.md b/docs/部署指南/Docker-Lite.md new file mode 100644 index 0000000..7bc4c91 --- /dev/null +++ b/docs/部署指南/Docker-Lite.md @@ -0,0 +1,244 @@ +# ConvertX-CN Lite 版 + +ConvertX-CN Lite 是專為一般使用者設計的輕量版本,提供快速部署與較小的 Docker Image 體積。 + +--- + +## 📦 什麼是 Lite 版? + +| 特性 | Full 版 | Lite 版 | +|------|---------|---------| +| **Image 大小** | 約 8-12 GB | 約 1.2-1.5 GB | +| **部署時間** | 較長(需下載大型模型) | 快速 | +| **記憶體需求** | 較高(AI 模型) | 較低 | +| **適用場景** | 進階使用者、需要 AI/OCR/翻譯 | 一般使用者、基本轉檔需求 | + +--- + +## ✅ Lite 版包含的功能 + +### 核心功能 +- ✅ **多語言 UI**:完整 i18n 介面(65 種語言) +- ✅ **檔案上傳/轉檔/下載**:完整流程支援 +- ✅ **轉檔進度與錯誤提示** + +### 轉換引擎 + +| 引擎 | 功能說明 | 支援格式 | +|------|----------|----------| +| **LibreOffice** | 文件轉檔 | DOC, DOCX, XLS, XLSX, PPT, PPTX, ODT, PDF... | +| **GraphicsMagick** | 圖片轉檔 | PNG, JPG, GIF, WEBP, BMP, TIFF... | +| **FFmpeg** | 影音轉檔(精簡版) | MP4, MP3, WAV, AVI, MKV, MOV... | +| **Pandoc** | 文件格式轉換 | Markdown, HTML, DOCX, LaTeX, EPUB... | + +### PDF 功能 + +| 功能 | 說明 | +|------|------| +| **PDF/A 轉換** | 使用 Ghostscript 轉換為 PDF/A-1b、PDF/A-2b | +| **PDF 防修改** | 使用 qpdf 設定權限保護 | +| **PDF 數位簽章** | 使用 PFX/PKCS#12 憑證簽章(單一簽章,不含 LTV) | + +--- + +## ❌ Lite 版未包含的功能 + +以下功能僅在 Full 版中提供: + +| 功能類別 | 功能說明 | +|----------|----------| +| **向量圖轉換** | Inkscape(SVG, PDF, PNG, EPS) | +| **高效能圖片** | VIPS(大型圖片處理) | +| **OCR** | Tesseract OCR 文字辨識 | +| **PDF 翻譯** | PDFMathTranslate、BabelDOC | +| **PDF 轉 Markdown** | MinerU 智能擷取 | +| **AI 模型** | YOLO、VLM 等深度學習模型 | +| **電子書** | Calibre(ePub、MOBI 轉換) | +| **CAD/3D** | assimp、OpenCascade | +| **PDF/A 驗證** | veraPDF | +| **長期驗證** | LTV、OCSP、CRL、TSA | +| **完整 TexLive** | 進階 LaTeX 排版 | + +--- + +## 🚀 快速開始 + +### Docker Run + +```bash +docker run -d \ + --name convertx-cn-lite \ + --restart unless-stopped \ + -p 3000:3000 \ + -v ./data:/app/data \ + -e TZ=Asia/Taipei \ + -e JWT_SECRET=你的隨機字串至少32字元 \ + convertx/convertx-cn:latest-lite +``` + +### Docker Compose + +```yaml +services: + convertx: + image: convertx/convertx-cn:latest-lite + container_name: convertx-cn-lite + restart: unless-stopped + ports: + - "3000:3000" + volumes: + - ./data:/app/data + environment: + - TZ=Asia/Taipei + - JWT_SECRET=你的隨機字串至少32字元 +``` + +```bash +docker compose up -d +``` + +--- + +## 🏷️ Image Tag 說明 + +| Tag | 說明 | +|-----|------| +| `convertx/convertx-cn:latest` | Full 版最新穩定版 | +| `convertx/convertx-cn:latest-lite` | Lite 版最新穩定版 | +| `convertx/convertx-cn:0.1.15` | Full 版指定版本 | +| `convertx/convertx-cn:0.1.15-lite` | Lite 版指定版本 | + +--- + +## 🔧 自行擴充 Lite 版功能 + +如果您使用 Lite 版但需要部分進階功能,可以透過 Docker Compose 擴充。 + +### 方法 1:使用 Docker Compose Override + +建立 `docker-compose.override.yml`: + +```yaml +# docker-compose.override.yml +# 在 Lite 版基礎上擴充功能 + +services: + convertx: + # 使用自定義 Dockerfile 擴充 + build: + context: . + dockerfile: Dockerfile.lite.custom +``` + +建立 `Dockerfile.lite.custom`: + +```dockerfile +# Dockerfile.lite.custom +# 基於 Lite 版擴充 + +FROM convertx/convertx-cn:latest-lite + +# 範例:新增 Tesseract OCR +RUN apt-get update && apt-get install -y --no-install-recommends \ + tesseract-ocr \ + tesseract-ocr-eng \ + tesseract-ocr-chi-tra \ + && rm -rf /var/lib/apt/lists/* + +# 範例:新增 Calibre +# RUN apt-get update && apt-get install -y --no-install-recommends \ +# calibre \ +# && rm -rf /var/lib/apt/lists/* +``` + +### 方法 2:直接使用 Full 版 + +如果需要完整功能,建議直接使用 Full 版: + +```yaml +services: + convertx: + image: convertx/convertx-cn:latest # Full 版 +``` + +### ⚠️ 重要提醒 + +- Lite 版**本身不包含** OCR、AI、翻譯等進階功能 +- 自行擴充會增加 Image 大小與維護成本 +- 如需完整功能,建議直接使用 Full 版 + +--- + +## 📊 Lite vs Full 功能對照表 + +| 功能類別 | 功能 | Lite | Full | +|----------|------|:----:|:----:| +| **UI** | 多語言介面(65 語言) | ✅ | ✅ | +| **UI** | 深色/淺色主題 | ✅ | ✅ | +| **轉檔** | 文件轉檔(LibreOffice) | ✅ | ✅ | +| **轉檔** | 圖片轉檔(GraphicsMagick) | ✅ | ✅ | +| **轉檔** | 圖片轉檔(ImageMagick) | ❌ | ✅ | +| **轉檔** | 影音轉檔(FFmpeg) | ✅ | ✅ | +| **轉檔** | 文件格式(Pandoc) | ✅ | ✅ | +| **轉檔** | 向量圖(Inkscape) | ❌ | ✅ | +| **轉檔** | 高效能圖片(VIPS) | ❌ | ✅ | +| **轉檔** | 電子書(Calibre) | ❌ | ✅ | +| **轉檔** | CAD/3D(assimp) | ❌ | ✅ | +| **PDF** | PDF/A 轉換 | ✅ | ✅ | +| **PDF** | PDF 防修改 | ✅ | ✅ | +| **PDF** | PDF 數位簽章 | ✅ | ✅ | +| **PDF** | PDF/A 驗證(veraPDF) | ❌ | ✅ | +| **PDF** | 長期驗證(LTV) | ❌ | ✅ | +| **OCR** | 文字辨識(Tesseract) | ❌ | ✅ | +| **OCR** | ocrmypdf | ❌ | ✅ | +| **AI** | PDF 翻譯(PDFMathTranslate) | ❌ | ✅ | +| **AI** | PDF 翻譯(BabelDOC) | ❌ | ✅ | +| **AI** | PDF 轉 Markdown(MinerU) | ❌ | ✅ | +| **字型** | 基本 CJK 字型 | ✅ | ✅ | +| **字型** | 完整 Noto 字型集 | ❌ | ✅ | +| **LaTeX** | 基本 LaTeX | ❌ | ✅ | +| **LaTeX** | 完整 TexLive CJK | ❌ | ✅ | + +--- + +## 💡 選擇建議 + +### 適合使用 Lite 版的情境 + +- 🔹 僅需要基本的文件/圖片/影音轉檔 +- 🔹 伺服器資源有限(VPS、NAS) +- 🔹 需要快速部署 +- 🔹 不需要 OCR、AI、翻譯功能 + +### 適合使用 Full 版的情境 + +- 🔹 需要 OCR 文字辨識 +- 🔹 需要 PDF 翻譯功能 +- 🔹 需要 MinerU PDF 轉 Markdown +- 🔹 需要電子書轉換(ePub、MOBI) +- 🔹 需要 CAD/3D 檔案處理 +- 🔹 需要進階 PDF/A 驗證 + +--- + +## 📝 版本更新 + +Lite 版與 Full 版使用相同的版本號規則,但 tag 不同: + +```bash +# 更新 Lite 版 +docker compose pull +docker compose up -d + +# 或指定版本 +docker pull convertx/convertx-cn:0.2.0-lite +``` + +--- + +## 🔗 相關連結 + +- [Docker Hub](https://hub.docker.com/r/convertx/convertx-cn) +- [GitHub Repository](https://github.com/pi-docket/ConvertX-CN) +- [Full 版部署指南](Docker.md) +- [環境變數說明](../配置設定/環境變數.md) diff --git a/docs/部署指南/Docker.md b/docs/部署指南/Docker.md index 5a23539..189500b 100644 --- a/docs/部署指南/Docker.md +++ b/docs/部署指南/Docker.md @@ -2,25 +2,47 @@ 本文件說明如何使用 Docker 部署 ConvertX-CN。 +> 💡 **Lite 版**:如果您只需要基本轉檔功能,可以使用 [Lite 版](Docker-Lite.md),Image 體積更小、部署更快。 + --- ## Docker Image 版本 ### 官方預建版(推薦) -| Tag | 說明 | -| ----------------------------- | ---------- | -| `convertx/convertx-cn:latest` | 最新穩定版 | -| `convertx/convertx-cn:v0.1.x` | 指定版本號 | +| Tag | 說明 | +| ---------------------------------- | -------------------- | +| `convertx/convertx-cn:latest` | Full 版最新穩定版 | +| `convertx/convertx-cn:latest-lite` | Lite 版最新穩定版 | +| `convertx/convertx-cn:v0.1.x` | Full 版指定版本號 | +| `convertx/convertx-cn:v0.1.x-lite` | Lite 版指定版本號 | + +### Full 版(預設) + +**Image 大小:約 8-12 GB** **內建功能:** - ✅ 核心轉換工具(FFmpeg、LibreOffice、ImageMagick 等) - ✅ OCR 支援:英文、繁/簡中文、日文、韓文、德文、法文 +- ✅ PDF 翻譯:PDFMathTranslate、BabelDOC +- ✅ PDF 轉 Markdown:MinerU - ✅ 字型:Noto CJK、Liberation、自訂中文字型 - ✅ TexLive(支援 CJK/德/法) -**Image 大小:約 4-6 GB** +### Lite 版(輕量版) + +**Image 大小:約 1.5-2.5 GB** + +**內建功能:** + +- ✅ 核心轉換工具(FFmpeg、LibreOffice、GraphicsMagick) +- ✅ 文件轉換(Pandoc) +- ✅ PDF/A 轉換、PDF 防修改、PDF 數位簽章 +- ✅ 基本 CJK 字型 +- ❌ 不含 OCR、AI 翻譯、MinerU、Calibre + +> 📖 Lite 版詳細說明請參閱 [Lite 版部署指南](Docker-Lite.md) ### 完整版(自行 Build)