From 165a02ea75301a1c1557ccc4d66350cf84043ace Mon Sep 17 00:00:00 2001 From: xiamuceer-j Date: Thu, 22 Jan 2026 11:03:28 +0800 Subject: [PATCH] =?UTF-8?q?test:=20=E6=B5=8B=E8=AF=95GitHub=E6=9E=84?= =?UTF-8?q?=E5=BB=BAdocker?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .github/workflows/docker-build.yml | 85 ++++++++++++++++++++++++++++++ Dockerfile | 67 ++++++++++++++++++----- 2 files changed, 139 insertions(+), 13 deletions(-) create mode 100644 .github/workflows/docker-build.yml diff --git a/.github/workflows/docker-build.yml b/.github/workflows/docker-build.yml new file mode 100644 index 0000000..84a79d8 --- /dev/null +++ b/.github/workflows/docker-build.yml @@ -0,0 +1,85 @@ +name: Build and Push Multi-Arch Docker Image + +on: + push: + branches: + - main + - master + tags: + - 'v*' + pull_request: + branches: + - main + - master + workflow_dispatch: # 允许手动触发 + +env: + DOCKER_IMAGE: mumujie/mumuainovel + +jobs: + build-and-push: + runs-on: ubuntu-latest + + steps: + - name: Checkout repository + uses: actions/checkout@v4 + + - name: Set up QEMU + uses: docker/setup-qemu-action@v3 + with: + platforms: linux/amd64,linux/arm64 + + - name: Set up Docker Buildx + uses: docker/setup-buildx-action@v3 + with: + driver-opts: | + image=moby/buildkit:master + network=host + + - name: Login to Docker Hub + if: github.event_name != 'pull_request' + uses: docker/login-action@v3 + with: + username: ${{ secrets.DOCKERHUB_USERNAME }} + password: ${{ secrets.DOCKERHUB_TOKEN }} + + - name: Extract metadata (tags, labels) + id: meta + uses: docker/metadata-action@v5 + with: + images: ${{ env.DOCKER_IMAGE }} + tags: | + # 对于main/master分支,打latest标签 + type=raw,value=latest,enable=${{ github.ref == 'refs/heads/main' || github.ref == 'refs/heads/master' }} + # 对于tag,使用版本号 + type=semver,pattern={{version}} + type=semver,pattern={{major}}.{{minor}} + type=semver,pattern={{major}} + # 使用分支名 + type=ref,event=branch + # 使用commit SHA + type=sha,prefix=sha- + + - name: Build and push Docker image + uses: docker/build-push-action@v5 + with: + context: . + file: ./Dockerfile + platforms: linux/amd64,linux/arm64 + push: ${{ github.event_name != 'pull_request' }} + tags: ${{ steps.meta.outputs.tags }} + labels: ${{ steps.meta.outputs.labels }} + cache-from: type=gha + cache-to: type=gha,mode=max + build-args: | + BUILDKIT_INLINE_CACHE=1 + + - name: Update Docker Hub Description + if: github.event_name != 'pull_request' && (github.ref == 'refs/heads/main' || github.ref == 'refs/heads/master') + uses: peter-evans/dockerhub-description@v4 + with: + username: ${{ secrets.DOCKERHUB_USERNAME }} + password: ${{ secrets.DOCKERHUB_TOKEN }} + repository: ${{ env.DOCKER_IMAGE }} + readme-filepath: ./README.md + continue-on-error: true \ No newline at end of file diff --git a/Dockerfile b/Dockerfile index be264fa..00990f7 100644 --- a/Dockerfile +++ b/Dockerfile @@ -1,16 +1,25 @@ # 多阶段构建 Dockerfile for AI Story Creator +# 支持多架构构建: linux/amd64, linux/arm64 + +# 构建参数 +ARG USE_CN_MIRROR=false + # 阶段1: 构建前端 FROM node:22-alpine AS frontend-builder +ARG USE_CN_MIRROR + WORKDIR /frontend # 复制前端依赖文件 COPY frontend/package*.json ./ -# 使用国内npm镜像加速 -RUN npm config set registry https://registry.npmmirror.com +# 根据参数决定是否使用国内npm镜像 +RUN if [ "$USE_CN_MIRROR" = "true" ]; then \ + npm config set registry https://registry.npmmirror.com; \ + fi -# 删除 package-lock.json 以SC避免因镜像源不一致导致的 404 错误 +# 删除 package-lock.json 以避免因镜像源不一致导致的 404 错误 RUN rm -f package-lock.json # 安装依赖 @@ -28,12 +37,18 @@ RUN npm run build # 阶段2: 构建最终镜像 FROM python:3.11-slim +ARG USE_CN_MIRROR +ARG TARGETPLATFORM +ARG TARGETARCH + # 设置工作目录 WORKDIR /app -# 使用国内镜像源加速 -RUN sed -i 's/deb.debian.org/mirrors.aliyun.com/g' /etc/apt/sources.list.d/debian.sources \ - && sed -i 's/security.debian.org/mirrors.aliyun.com/g' /etc/apt/sources.list.d/debian.sources +# 根据参数决定是否使用国内镜像源 +RUN if [ "$USE_CN_MIRROR" = "true" ]; then \ + sed -i 's/deb.debian.org/mirrors.aliyun.com/g' /etc/apt/sources.list.d/debian.sources && \ + sed -i 's/security.debian.org/mirrors.aliyun.com/g' /etc/apt/sources.list.d/debian.sources; \ + fi # 安装系统依赖(添加数据库工具) RUN apt-get update && apt-get install -y \ @@ -45,13 +60,40 @@ RUN apt-get update && apt-get install -y \ # 复制后端依赖文件 COPY backend/requirements.txt ./ -# 先从PyTorch官方源安装CPU版本的torch(避免GPU依赖) -RUN pip install --no-cache-dir torch==2.7.0 --index-url https://download.pytorch.org/whl/cpu +# 根据架构安装PyTorch CPU版本 +# arm64架构使用pip直接安装,amd64使用PyTorch官方CPU源 +RUN if [ "$TARGETARCH" = "arm64" ]; then \ + pip install --no-cache-dir torch --index-url https://download.pytorch.org/whl/cpu || \ + pip install --no-cache-dir torch; \ + else \ + pip install --no-cache-dir torch --index-url https://download.pytorch.org/whl/cpu; \ + fi -# 再安装其他Python依赖(使用阿里云镜像加速) -RUN pip install --no-cache-dir -r requirements.txt -i https://mirrors.aliyun.com/pypi/simple/ +# 安装其他Python依赖 +RUN if [ "$USE_CN_MIRROR" = "true" ]; then \ + pip install --no-cache-dir -r requirements.txt -i https://mirrors.aliyun.com/pypi/simple/; \ + else \ + pip install --no-cache-dir -r requirements.txt; \ + fi -# 复制后端代码(包含embedding模型) +# 创建embedding目录 +RUN mkdir -p /app/embedding + +# 设置 Sentence-Transformers 缓存目录 +ENV SENTENCE_TRANSFORMERS_HOME=/app/embedding + +# 下载 embedding 模型(从 HuggingFace) +# 使用 Python 脚本预下载模型,这样运行时不需要网络 +RUN python -c "\ +from sentence_transformers import SentenceTransformer; \ +import os; \ +os.environ['SENTENCE_TRANSFORMERS_HOME'] = '/app/embedding'; \ +print('Downloading sentence-transformers/paraphrase-multilingual-MiniLM-L12-v2...'); \ +model = SentenceTransformer('sentence-transformers/paraphrase-multilingual-MiniLM-L12-v2'); \ +print('Model downloaded successfully!'); \ +" + +# 复制后端代码(不包含embedding,因为已经下载了) COPY backend/ ./ # 从前端构建阶段复制构建好的静态文件 @@ -77,11 +119,10 @@ ENV PYTHONUNBUFFERED=1 ENV APP_HOST=0.0.0.0 ENV APP_PORT=8000 -# 设置Transformers和Sentence-Transformers离线模式 +# 设置运行时为离线模式(模型已在构建时下载) ENV TRANSFORMERS_OFFLINE=1 ENV HF_DATASETS_OFFLINE=1 ENV HF_HUB_OFFLINE=1 -ENV SENTENCE_TRANSFORMERS_HOME=/app/embedding # 健康检查 HEALTHCHECK --interval=30s --timeout=10s --start-period=5s --retries=3 \