From 769aca10dbec15f12fa377fe0d3d3fbedd90b7fa Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E5=9C=A3=E8=BE=BE=E7=94=9F=E7=89=A9=E5=A4=9A?= Date: Thu, 5 Feb 2026 21:34:57 +0800 Subject: [PATCH] =?UTF-8?q?=E6=B7=BB=E5=8A=A0=20Docker=20=E6=9E=84?= =?UTF-8?q?=E5=BB=BA=E5=B7=A5=E4=BD=9C=E6=B5=81=E5=92=8C=E5=AE=8C=E6=95=B4?= =?UTF-8?q?=E5=BA=94=E7=94=A8=E9=95=9C=E5=83=8F=E7=9A=84=20Dockerfile?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .github/workflows/docker-build.yml | 76 ++++++++++++++++++++++++ Dockerfile.complete | 92 ++++++++++++++++++++++++++++++ 2 files changed, 168 insertions(+) create mode 100644 .github/workflows/docker-build.yml create mode 100644 Dockerfile.complete diff --git a/.github/workflows/docker-build.yml b/.github/workflows/docker-build.yml new file mode 100644 index 00000000..bb8fd204 --- /dev/null +++ b/.github/workflows/docker-build.yml @@ -0,0 +1,76 @@ +name: Build Complete Docker Image + +on: + push: + tags: + - 'v*' # 在推送 tag 时触发 (如 v1.0.0) + +jobs: + build: + runs-on: ubuntu-latest + + steps: + - name: Checkout Code + uses: actions/checkout@v4 + + - name: Extract Version from Tag + id: get_version + run: | + # 获取 tag 名称 (如 refs/tags/v1.0.0 -> v1.0.0) + VERSION=${GITHUB_REF#refs/tags/} + echo "version=$VERSION" >> $GITHUB_OUTPUT + echo "Tag version: $VERSION" + + - name: Set up Docker Buildx + uses: docker/setup-buildx-action@v3 + + - name: Build Docker Image + run: | + VERSION="${{ steps.get_version.outputs.version }}" + IMAGE_NAME="bilinote:${VERSION}" + + echo "Building image: ${IMAGE_NAME}" + + # 构建镜像 + docker build -f Dockerfile.complete -t ${IMAGE_NAME} . + + # 保存镜像为 tar 文件 + docker save ${IMAGE_NAME} -o bilinote-${VERSION}.tar + + # 显示镜像信息 + echo "Image built successfully!" + docker images bilinote:${VERSION} + + - name: Upload Docker Image Artifact + uses: actions/upload-artifact@v4 + with: + name: bilinote-${{ steps.get_version.outputs.version }} + path: bilinote-${{ steps.get_version.outputs.version }}.tar + retention-days: 90 + + - name: Generate Usage Instructions + run: | + VERSION="${{ steps.get_version.outputs.version }}" + echo "==========================================" + echo "Docker Image Build Complete!" + echo "==========================================" + echo "" + echo "Image Name: bilinote:${VERSION}" + echo "Artifact: bilinote-${VERSION}.tar" + echo "" + echo "To use this Docker image:" + echo "1. Download the artifact from this workflow run" + echo "2. Load the image:" + echo " docker load < bilinote-${VERSION}.tar" + echo "3. Run the container:" + echo " docker run -d -p 80:80 --name bilinote bilinote:${VERSION}" + echo "" + echo "Or with environment variables:" + echo " docker run -d -p 80:80 \\" + echo " -e BACKEND_PORT=8483 \\" + echo " -e BACKEND_HOST=0.0.0.0 \\" + echo " -v /path/to/data:/app/backend/data \\" + echo " --name bilinote bilinote:${VERSION}" + echo "" + echo "Access the application at: http://localhost:80" + echo "==========================================" diff --git a/Dockerfile.complete b/Dockerfile.complete new file mode 100644 index 00000000..ba38edbf --- /dev/null +++ b/Dockerfile.complete @@ -0,0 +1,92 @@ +# === 阶段1:构建 Backend === +FROM python:3.11-slim AS backend-builder + +RUN rm -f /etc/apt/sources.list && \ + rm -rf /etc/apt/sources.list.d/* && \ + echo "deb https://mirrors.tuna.tsinghua.edu.cn/debian bookworm main contrib non-free non-free-firmware" > /etc/apt/sources.list && \ + echo "deb https://mirrors.tuna.tsinghua.edu.cn/debian bookworm-updates main contrib non-free non-free-firmware" >> /etc/apt/sources.list && \ + echo "deb https://mirrors.tuna.tsinghua.edu.cn/debian-security bookworm-security main contrib non-free non-free-firmware" >> /etc/apt/sources.list && \ + apt-get update && \ + apt-get install -y ffmpeg && \ + rm -rf /var/lib/apt/lists/* + +ENV PATH="/usr/bin:${PATH}" +ENV HF_ENDPOINT=https://hf-mirror.com + +WORKDIR /tmp/backend +COPY ./backend /tmp/backend +RUN pip install --no-cache-dir -i https://pypi.tuna.tsinghua.edu.cn/simple -r requirements.txt + +# === 阶段2:构建 Frontend === +FROM node:18-alpine AS frontend-builder + +RUN npm install -g pnpm +WORKDIR /tmp/frontend +COPY ./BillNote_frontend /tmp/frontend +RUN pnpm install && pnpm run build + +# === 阶段3:完整应用镜像 === +FROM python:3.11-slim + +# 安装必要的运行时依赖 +RUN rm -f /etc/apt/sources.list && \ + rm -rf /etc/apt/sources.list.d/* && \ + echo "deb https://mirrors.tuna.tsinghua.edu.cn/debian bookworm main contrib non-free non-free-firmware" > /etc/apt/sources.list && \ + echo "deb https://mirrors.tuna.tsinghua.edu.cn/debian bookworm-updates main contrib non-free non-free-firmware" >> /etc/apt/sources.list && \ + echo "deb https://mirrors.tuna.tsinghua.edu.cn/debian-security bookworm-security main contrib non-free non-free-firmware" >> /etc/apt/sources.list && \ + apt-get update && \ + apt-get install -y ffmpeg nginx supervisor procps && \ + rm -rf /var/lib/apt/lists/* + +ENV PATH="/usr/bin:${PATH}" +ENV HF_ENDPOINT=https://hf-mirror.com +ENV PYTHONUNBUFFERED=1 + +# 复制 Python 依赖 +COPY --from=backend-builder /usr/local/lib/python3.11/site-packages /usr/local/lib/python3.11/site-packages +COPY --from=backend-builder /usr/local/bin /usr/local/bin + +# 复制 backend 代码 +COPY ./backend /app/backend +WORKDIR /app/backend + +# 复制前端静态文件到 nginx +COPY --from=frontend-builder /tmp/frontend/dist /usr/share/nginx/html + +# 配置 nginx +RUN rm -rf /etc/nginx/conf.d/default.conf +COPY ./nginx/default.conf /etc/nginx/conf.d/default.conf + +# 创建 supervisor 配置 +RUN mkdir -p /var/log/supervisor +COPY <