From 6c68a7c51e2f5bf295ebfe2c98b9cc9c2115d78a Mon Sep 17 00:00:00 2001 From: vinland100 Date: Wed, 7 Jan 2026 17:14:03 +0800 Subject: [PATCH] feat: Introduce Gitea CI for Docker image builds/pushes and update docker-compose to use new registry images and persistent volumes. --- .gitea/workflows/build.yml | 44 ++++ .github/FUNDING.yml | 15 -- .github/workflows/docker-publish.yml | 129 ----------- .github/workflows/release.yml | 271 ------------------------ .github/workflows/scheduled-release.yml | 79 ------- docker-compose.prod.yml | 18 +- docker-compose.yml | 6 +- 7 files changed, 60 insertions(+), 502 deletions(-) create mode 100644 .gitea/workflows/build.yml delete mode 100644 .github/FUNDING.yml delete mode 100644 .github/workflows/docker-publish.yml delete mode 100644 .github/workflows/release.yml delete mode 100644 .github/workflows/scheduled-release.yml diff --git a/.gitea/workflows/build.yml b/.gitea/workflows/build.yml new file mode 100644 index 0000000..291552e --- /dev/null +++ b/.gitea/workflows/build.yml @@ -0,0 +1,44 @@ +name: Build and Push CodeReview +on: + push: + branches: + - main + - master + +jobs: + build: + runs-on: ubuntu-latest + steps: + - name: Checkout + uses: actions/checkout@v4 + + - name: Set up Docker Buildx + uses: docker/setup-buildx-action@v3 + + - name: Login to Registry + uses: docker/login-action@v3 + with: + registry: sl.vrgon.com:3000 + username: ${{ gitea.actor }} + password: ${{ secrets.GITEA_TOKEN }} + + - name: Build and Push Backend + uses: docker/build-push-action@v5 + with: + context: ./backend + push: true + tags: sl.vrgon.com:3000/zk_senlan/codereview:backend + + - name: Build and Push Frontend + uses: docker/build-push-action@v5 + with: + context: ./frontend + push: true + tags: sl.vrgon.com:3000/zk_senlan/codereview:frontend + + - name: Build and Push Sandbox + uses: docker/build-push-action@v5 + with: + context: ./docker/sandbox + push: true + tags: sl.vrgon.com:3000/zk_senlan/codereview:sandbox diff --git a/.github/FUNDING.yml b/.github/FUNDING.yml deleted file mode 100644 index 93166a0..0000000 --- a/.github/FUNDING.yml +++ /dev/null @@ -1,15 +0,0 @@ -# These are supported funding model platforms -github: # 中国大陆暂不支持,留空或忽略 -patreon: # 如果有 Patreon,可替换为用户名 -open_collective: # 如果有 Open Collective,可替换为用户名 -ko_fi: # 如果有 Ko-fi,可替换为用户名 -tidelift: # 如果有 Tidelift,可替换为 platform-name/package-name -community_bridge: # 如果有 Community Bridge,可替换为 project-name -liberapay: # 如果有 Liberapay,可替换为用户名 -issuehunt: # 如果有 IssueHunt,可替换为用户名 -lfx_crowdfunding: # 如果有 LFX Crowdfunding,可替换为 project-name -polar: # 如果有 Polar,可替换为用户名 -buy_me_a_coffee: # 如果有 Buy Me a Coffee,可替换为用户名 -thanks_dev: # 如果有 thanks.dev,可替换为用户名 -custom: - - "https://github.com/lintsinghua/lintsinghua.github.io/issues/1" diff --git a/.github/workflows/docker-publish.yml b/.github/workflows/docker-publish.yml deleted file mode 100644 index 2656f76..0000000 --- a/.github/workflows/docker-publish.yml +++ /dev/null @@ -1,129 +0,0 @@ -name: Docker Publish - -# 只构建并推送 Docker 镜像,不创建 Release 或 Tag -on: - workflow_dispatch: - inputs: - tag: - description: '镜像标签 (例如: latest, dev, v3.0.0)' - required: true - default: 'latest' - type: string - build_frontend: - description: '构建前端镜像' - required: false - type: boolean - default: true - build_backend: - description: '构建后端镜像' - required: false - type: boolean - default: true - build_sandbox: - description: '构建沙箱镜像' - required: false - type: boolean - default: true - -jobs: - build-and-push: - name: 构建并推送镜像 - runs-on: ubuntu-latest - - permissions: - contents: read - packages: write - - steps: - - name: 检出代码 - uses: actions/checkout@v4 - - - name: 设置 Node.js - if: ${{ github.event.inputs.build_frontend == 'true' }} - uses: actions/setup-node@v4 - with: - node-version: '20' - - - name: 安装 pnpm - if: ${{ github.event.inputs.build_frontend == 'true' }} - uses: pnpm/action-setup@v4 - with: - version: 9 - - - name: 安装前端依赖 - if: ${{ github.event.inputs.build_frontend == 'true' }} - working-directory: ./frontend - run: pnpm install --frozen-lockfile - - - name: 构建前端项目 - if: ${{ github.event.inputs.build_frontend == 'true' }} - working-directory: ./frontend - run: pnpm build - env: - VITE_USE_LOCAL_DB: 'true' - - - name: 登录到 GitHub Container Registry - uses: docker/login-action@v3 - with: - registry: ghcr.io - username: ${{ github.actor }} - password: ${{ secrets.GITHUB_TOKEN }} - - - name: 设置 QEMU - uses: docker/setup-qemu-action@v3 - - - name: 设置 Docker Buildx - uses: docker/setup-buildx-action@v3 - - - name: 构建并推送前端 Docker 镜像 - if: ${{ github.event.inputs.build_frontend == 'true' }} - uses: docker/build-push-action@v5 - with: - context: ./frontend - file: ./frontend/Dockerfile - push: true - platforms: linux/amd64,linux/arm64 - tags: | - ghcr.io/${{ github.repository_owner }}/deepaudit-frontend:${{ github.event.inputs.tag }} - cache-from: type=gha,scope=frontend - cache-to: type=gha,mode=max,scope=frontend - - - name: 构建并推送后端 Docker 镜像 - if: ${{ github.event.inputs.build_backend == 'true' }} - uses: docker/build-push-action@v5 - with: - context: ./backend - file: ./backend/Dockerfile - push: true - platforms: linux/amd64,linux/arm64 - tags: | - ghcr.io/${{ github.repository_owner }}/deepaudit-backend:${{ github.event.inputs.tag }} - cache-from: type=gha,scope=backend - cache-to: type=gha,mode=max,scope=backend - - - name: 构建并推送沙箱 Docker 镜像 - if: ${{ github.event.inputs.build_sandbox == 'true' }} - uses: docker/build-push-action@v5 - with: - context: ./docker/sandbox - file: ./docker/sandbox/Dockerfile - push: true - platforms: linux/amd64,linux/arm64 - tags: | - ghcr.io/${{ github.repository_owner }}/deepaudit-sandbox:${{ github.event.inputs.tag }} - cache-from: type=gha,scope=sandbox - cache-to: type=gha,mode=max,scope=sandbox - - - name: 输出镜像信息 - run: | - echo "## 镜像已推送到 GHCR" >> $GITHUB_STEP_SUMMARY - echo "" >> $GITHUB_STEP_SUMMARY - if [ "${{ github.event.inputs.build_frontend }}" == "true" ]; then - echo "- \`ghcr.io/${{ github.repository_owner }}/deepaudit-frontend:${{ github.event.inputs.tag }}\`" >> $GITHUB_STEP_SUMMARY - fi - if [ "${{ github.event.inputs.build_backend }}" == "true" ]; then - echo "- \`ghcr.io/${{ github.repository_owner }}/deepaudit-backend:${{ github.event.inputs.tag }}\`" >> $GITHUB_STEP_SUMMARY - fi - if [ "${{ github.event.inputs.build_sandbox }}" == "true" ]; then - echo "- \`ghcr.io/${{ github.repository_owner }}/deepaudit-sandbox:${{ github.event.inputs.tag }}\`" >> $GITHUB_STEP_SUMMARY - fi diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml deleted file mode 100644 index eafba48..0000000 --- a/.github/workflows/release.yml +++ /dev/null @@ -1,271 +0,0 @@ -name: Release - -# 触发条件 -on: - # 手动触发 - workflow_dispatch: - inputs: - version: - description: '版本号 (例如: v3.0.0)' - required: true - type: string - prerelease: - description: '是否为预发布版本' - required: false - type: boolean - default: false - - # 当推送 tag 时自动触发(格式:v*.*.* ) - push: - tags: - - 'v*.*.*' - -jobs: - build-and-release: - name: 构建并发布 - runs-on: ubuntu-latest - - permissions: - contents: write - packages: write - - steps: - # 1. 检出代码 - - name: 检出代码 - uses: actions/checkout@v4 - with: - fetch-depth: 0 - - # 2. 设置 Node.js 环境(用于前端构建) - - name: 设置 Node.js - uses: actions/setup-node@v4 - with: - node-version: '20' - - # 3. 安装 pnpm - - name: 安装 pnpm - uses: pnpm/action-setup@v4 - with: - version: 9 - - # 4. 获取 pnpm store 目录 - - name: 获取 pnpm store 目录 - shell: bash - run: | - echo "STORE_PATH=$(pnpm store path --silent)" >> $GITHUB_ENV - - # 5. 设置 pnpm 缓存 - - name: 设置 pnpm 缓存 - uses: actions/cache@v4 - with: - path: ${{ env.STORE_PATH }} - key: ${{ runner.os }}-pnpm-store-${{ hashFiles('**/pnpm-lock.yaml') }} - restore-keys: | - ${{ runner.os }}-pnpm-store- - - # 6. 安装前端依赖 - - name: 安装前端依赖 - working-directory: ./frontend - run: pnpm install --frozen-lockfile - - # 7. 构建前端项目 - - name: 构建前端项目 - working-directory: ./frontend - run: pnpm build - - - # 8. 设置 Python 环境(用于后端) - - name: 设置 Python - uses: actions/setup-python@v5 - with: - python-version: '3.13' - - # 9. 确定版本号 - - name: 确定版本号 - id: version - run: | - if [ "${{ github.event_name }}" == "workflow_dispatch" ]; then - echo "VERSION=${{ github.event.inputs.version }}" >> $GITHUB_OUTPUT - echo "IS_PRERELEASE=${{ github.event.inputs.prerelease }}" >> $GITHUB_OUTPUT - else - echo "VERSION=${GITHUB_REF#refs/tags/}" >> $GITHUB_OUTPUT - echo "IS_PRERELEASE=false" >> $GITHUB_OUTPUT - fi - VERSION_NO_V="${VERSION#v}" - echo "VERSION_NO_V=$VERSION_NO_V" >> $GITHUB_OUTPUT - - # 10. 打包构建产物 - - name: 打包构建产物 - run: | - # 创建发布目录 - mkdir -p release - - # 打包前端构建产物 - tar -czf release/deepaudit-frontend-${{ steps.version.outputs.VERSION }}.tar.gz -C frontend/dist . - - # 打包后端源码 - tar -czf release/deepaudit-backend-${{ steps.version.outputs.VERSION }}.tar.gz \ - --exclude=backend/.venv \ - --exclude=backend/.env \ - --exclude=backend/__pycache__ \ - --exclude=backend/uploads \ - backend/ - - # 打包 Docker 配置文件(包含 Agent 模式配置) - tar -czf release/deepaudit-docker-${{ steps.version.outputs.VERSION }}.tar.gz \ - docker-compose.yml \ - backend/Dockerfile \ - backend/.dockerignore \ - frontend/Dockerfile \ - frontend/.dockerignore \ - frontend/docker-entrypoint.sh \ - backend/env.example \ - frontend/.env.example \ - docker/sandbox/ - - # 打包完整源码(包括配置文件) - tar -czf release/deepaudit-source-${{ steps.version.outputs.VERSION }}.tar.gz \ - --exclude=frontend/node_modules \ - --exclude=frontend/dist \ - --exclude=backend/.venv \ - --exclude=backend/.env \ - --exclude=backend/uploads \ - --exclude=.git \ - --exclude=release \ - . - - # 创建 checksums - cd release - sha256sum * > checksums.txt - cd .. - - # 11. 生成更新日志 - - name: 生成更新日志 - id: changelog - run: | - # 获取上一个 tag - PREVIOUS_TAG=$(git describe --tags --abbrev=0 HEAD^ 2>/dev/null || echo "") - - if [ -z "$PREVIOUS_TAG" ]; then - echo "这是第一个发布版本" > CHANGELOG.md - git log --pretty=format:"- %s (%h)" >> CHANGELOG.md - else - echo "自 $PREVIOUS_TAG 以来的变更:" > CHANGELOG.md - echo "" >> CHANGELOG.md - git log $PREVIOUS_TAG..HEAD --pretty=format:"- %s (%h)" >> CHANGELOG.md - fi - - echo "" >> CHANGELOG.md - echo "" >> CHANGELOG.md - echo "## 🚀 v3.0.0 新特性" >> CHANGELOG.md - echo "" >> CHANGELOG.md - echo "- 🤖 **Multi-Agent 架构**: Orchestrator/Analysis/Recon/Verification 多智能体协作" >> CHANGELOG.md - echo "- 🧠 **RAG 知识库增强**: 代码语义理解 + CWE/CVE 漏洞知识库" >> CHANGELOG.md - echo "- 🔒 **沙箱漏洞验证**: Docker 安全容器自动执行 PoC" >> CHANGELOG.md - echo "- 🛠️ **专业安全工具集成**: Semgrep, Bandit, Gitleaks, OSV-Scanner" >> CHANGELOG.md - echo "- 🐛 **稳定性增强**: 修复多智能体工具调用循环、UI 显示及 Docker 环境兼容性问题" >> CHANGELOG.md - echo "" >> CHANGELOG.md - echo "## 📦 下载说明" >> CHANGELOG.md - echo "" >> CHANGELOG.md - echo "### 构建产物" >> CHANGELOG.md - echo "- \`deepaudit-frontend-*.tar.gz\`: 前端构建产物(用于生产部署)" >> CHANGELOG.md - echo "- \`deepaudit-backend-*.tar.gz\`: 后端源码包" >> CHANGELOG.md - echo "- \`deepaudit-docker-*.tar.gz\`: Docker 配置文件(包含沙箱配置)" >> CHANGELOG.md - echo "- \`deepaudit-source-*.tar.gz\`: 完整源码包" >> CHANGELOG.md - echo "- \`checksums.txt\`: 文件校验和" >> CHANGELOG.md - echo "" >> CHANGELOG.md - echo "### Docker 镜像" >> CHANGELOG.md - echo "- Frontend: \`ghcr.io/${{ github.repository_owner }}/deepaudit-frontend:${{ steps.version.outputs.VERSION }}\`" >> CHANGELOG.md - echo "- Backend: \`ghcr.io/${{ github.repository_owner }}/deepaudit-backend:${{ steps.version.outputs.VERSION }}\`" >> CHANGELOG.md - echo "" >> CHANGELOG.md - echo "### 快速部署" >> CHANGELOG.md - echo "\`\`\`bash" >> CHANGELOG.md - echo "# 部署" >> CHANGELOG.md - echo "docker compose up -d" >> CHANGELOG.md - echo "\`\`\`" >> CHANGELOG.md - - # 12. 创建 GitHub Release - - name: 创建 Release - uses: softprops/action-gh-release@v2 - with: - tag_name: ${{ steps.version.outputs.VERSION }} - name: Release ${{ steps.version.outputs.VERSION }} - body_path: CHANGELOG.md - draft: false - prerelease: ${{ steps.version.outputs.IS_PRERELEASE }} - files: | - release/* - generate_release_notes: true - env: - GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} - - # 13. 登录 GitHub Container Registry - - name: 登录到 GitHub Container Registry - uses: docker/login-action@v3 - with: - registry: ghcr.io - username: ${{ github.actor }} - password: ${{ secrets.GITHUB_TOKEN }} - - # 14. 设置 QEMU(用于多架构构建) - - name: 设置 QEMU - uses: docker/setup-qemu-action@v3 - - # 15. 设置 Docker Buildx - - name: 设置 Docker Buildx - uses: docker/setup-buildx-action@v3 - - # 16. 构建并推送前端 Docker 镜像 - - name: 构建并推送前端 Docker 镜像 - uses: docker/build-push-action@v5 - with: - context: ./frontend - file: ./frontend/Dockerfile - push: true - platforms: linux/amd64,linux/arm64 - tags: | - ghcr.io/${{ github.repository_owner }}/deepaudit-frontend:${{ steps.version.outputs.VERSION }} - ghcr.io/${{ github.repository_owner }}/deepaudit-frontend:latest - cache-from: type=gha,scope=frontend - cache-to: type=gha,mode=max,scope=frontend - - # 17. 构建并推送后端 Docker 镜像 - - name: 构建并推送后端 Docker 镜像 - uses: docker/build-push-action@v5 - with: - context: ./backend - file: ./backend/Dockerfile - push: true - platforms: linux/amd64,linux/arm64 - tags: | - ghcr.io/${{ github.repository_owner }}/deepaudit-backend:${{ steps.version.outputs.VERSION }} - ghcr.io/${{ github.repository_owner }}/deepaudit-backend:latest - cache-from: type=gha,scope=backend - cache-to: type=gha,mode=max,scope=backend - - # 18. 构建并推送沙箱 Docker 镜像 - - name: 构建并推送沙箱 Docker 镜像 - uses: docker/build-push-action@v5 - with: - context: ./docker/sandbox - file: ./docker/sandbox/Dockerfile - push: true - platforms: linux/amd64,linux/arm64 - tags: | - ghcr.io/${{ github.repository_owner }}/deepaudit-sandbox:${{ steps.version.outputs.VERSION }} - ghcr.io/${{ github.repository_owner }}/deepaudit-sandbox:latest - cache-from: type=gha,scope=sandbox - cache-to: type=gha,mode=max,scope=sandbox - - # 19. 更新 README 中的版本号 - - name: 更新 README 版本号 - if: github.event_name == 'push' - run: | - VERSION="${{ steps.version.outputs.VERSION_NO_V }}" - sed -i "s/version-[0-9]*\.[0-9]*\.[0-9]*/version-$VERSION/g" README.md - - git config user.name "github-actions[bot]" - git config user.email "github-actions[bot]@users.noreply.github.com" - git add README.md - git commit -m "docs: update README version to $VERSION" || true - git push origin HEAD:main || true diff --git a/.github/workflows/scheduled-release.yml b/.github/workflows/scheduled-release.yml deleted file mode 100644 index beab1b6..0000000 --- a/.github/workflows/scheduled-release.yml +++ /dev/null @@ -1,79 +0,0 @@ -name: 定时发布 - -# 定时触发(每月1号自动发布) -on: - schedule: - # 每月1号的 UTC 00:00 (北京时间 08:00) - - cron: '0 0 1 * *' - - # 也支持手动触发 - workflow_dispatch: - -jobs: - check-and-release: - name: 检查并发布 - runs-on: ubuntu-latest - - permissions: - contents: write - - steps: - # 1. 检出代码 - - name: 检出代码 - uses: actions/checkout@v4 - with: - fetch-depth: 0 - - # 2. 检查是否有新的提交 - - name: 检查是否有新提交 - id: check - run: | - # 获取最后一个 tag - LAST_TAG=$(git describe --tags --abbrev=0 2>/dev/null || echo "") - - if [ -z "$LAST_TAG" ]; then - echo "has_changes=true" >> $GITHUB_OUTPUT - echo "version=v2.0.0" >> $GITHUB_OUTPUT - else - # 检查自上次 tag 以来是否有新的提交 - COMMITS_SINCE_TAG=$(git rev-list $LAST_TAG..HEAD --count) - - if [ "$COMMITS_SINCE_TAG" -gt "0" ]; then - echo "has_changes=true" >> $GITHUB_OUTPUT - - # 自动计算下一个版本号(小版本号 +1) - VERSION_NO_V="${LAST_TAG#v}" - IFS='.' read -r -a VERSION_PARTS <<< "$VERSION_NO_V" - MAJOR="${VERSION_PARTS[0]}" - MINOR="${VERSION_PARTS[1]}" - PATCH="${VERSION_PARTS[2]}" - - # 增加 minor 版本 - NEXT_MINOR=$((MINOR + 1)) - NEXT_VERSION="v${MAJOR}.${NEXT_MINOR}.0" - - echo "version=$NEXT_VERSION" >> $GITHUB_OUTPUT - else - echo "has_changes=false" >> $GITHUB_OUTPUT - fi - fi - - # 3. 创建新的 tag - - name: 创建版本标签 - if: steps.check.outputs.has_changes == 'true' - run: | - git config user.name "github-actions[bot]" - git config user.email "github-actions[bot]@users.noreply.github.com" - git tag -a ${{ steps.check.outputs.version }} -m "自动发布: ${{ steps.check.outputs.version }}" - git push origin ${{ steps.check.outputs.version }} - - # 4. 触发发布工作流 - - name: 触发发布 - if: steps.check.outputs.has_changes == 'true' - run: | - echo "✅ 新版本 ${{ steps.check.outputs.version }} 已创建" - echo "🚀 Release 工作流将自动开始构建和发布" - echo "📦 将发布以下组件:" - echo " - 前端 Docker 镜像" - echo " - 后端 Docker 镜像" - echo " - 构建产物和源码包" diff --git a/docker-compose.prod.yml b/docker-compose.prod.yml index 1aca2f6..803a10d 100644 --- a/docker-compose.prod.yml +++ b/docker-compose.prod.yml @@ -36,10 +36,13 @@ services: - deepaudit-network backend: - image: ghcr.io/lintsinghua/deepaudit-backend:latest + image: sl.vrgon.com:3000/zk_senlan/codereview:backend restart: unless-stopped volumes: - backend_uploads:/app/uploads + - chroma_data:/app/data/vector_db + - ci_workspace:/app/data/ci_workspace + - ci_vectordb:/app/data/ci_vectordb - /var/run/docker.sock:/var/run/docker.sock ports: - "8000:8000" @@ -48,7 +51,7 @@ services: - REDIS_URL=redis://redis:6379/0 - AGENT_ENABLED=true - SANDBOX_ENABLED=true - - SANDBOX_IMAGE=ghcr.io/lintsinghua/deepaudit-sandbox:latest + - SANDBOX_IMAGE=sl.vrgon.com:3000/zk_senlan/codereview:sandbox # LLM 配置 - 请根据需要修改 - LLM_PROVIDER=${LLM_PROVIDER:-openai} - LLM_MODEL=${LLM_MODEL:-gpt-4o} @@ -75,7 +78,7 @@ services: # 数据库迁移服务 - 在后端启动前自动执行 db-migrate: - image: ghcr.io/lintsinghua/deepaudit-backend:latest + image: sl.vrgon.com:3000/zk_senlan/codereview:backend restart: "no" environment: - DATABASE_URL=postgresql+asyncpg://postgres:postgres@db:5432/deepaudit @@ -87,10 +90,10 @@ services: - deepaudit-network frontend: - image: ghcr.io/lintsinghua/deepaudit-frontend:latest + image: sl.vrgon.com:3000/zk_senlan/codereview:frontend restart: unless-stopped ports: - - "3000:80" + - "83:80" # Nginx 监听 80 端口 environment: # 禁用代理 - nginx 需要直连后端 - HTTP_PROXY= @@ -105,7 +108,7 @@ services: # 预拉取沙箱镜像(后端会按需调用) sandbox-pull: - image: ghcr.io/lintsinghua/deepaudit-sandbox:latest + image: sl.vrgon.com:3000/zk_senlan/codereview:sandbox restart: "no" command: echo "Sandbox image ready" @@ -116,4 +119,7 @@ networks: volumes: postgres_data: backend_uploads: + chroma_data: + ci_workspace: + ci_vectordb: redis_data: diff --git a/docker-compose.yml b/docker-compose.yml index 821495e..a542b89 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -32,6 +32,7 @@ services: backend: build: context: ./backend + image: code-review:backend restart: unless-stopped # 允许容器通过 host.docker.internal 访问宿主机 extra_hosts: @@ -52,7 +53,7 @@ services: - REDIS_URL=redis://redis:6379/0 - AGENT_ENABLED=true - SANDBOX_ENABLED=true - - SANDBOX_IMAGE=deepaudit/sandbox:latest # 使用本地构建的沙箱镜像 + - SANDBOX_IMAGE=code-review:sandbox # 使用本地构建的沙箱镜像 # 指定 embedding 服务地址 - EMBEDDING_PROVIDER=openai - EMBEDDING_MODEL=text-embedding-v4 @@ -74,6 +75,7 @@ services: frontend: build: context: ./frontend + image: code-review:frontend restart: unless-stopped volumes: # - ./frontend/dist:/usr/share/nginx/html:ro # 挂载构建产物,本地 pnpm build 后自动生效 @@ -113,7 +115,7 @@ services: build: context: ./docker/sandbox dockerfile: Dockerfile - image: deepaudit/sandbox:latest + image: code-review:sandbox restart: "no" command: echo "Sandbox image built successfully"