feat(ci): build dashboard images on VPS (SSD) instead of NAS HDD
Deploy Dashboard (Main) / Backend Tests (push) Has been cancelled
Deploy Dashboard (Main) / Build Docker Image (push) Has been cancelled
Deploy Dashboard (Main) / Deploy to Production (push) Has been cancelled
Deploy Dashboard (Main) / Frontend Tests (push) Has been cancelled

- Add build-image job (runs-on: vps) for deploy.yml (main) - builds with
  Podman on server2, pipes finished image to NAS via SSH, retags
- Add build-image-dev job (runs-on: vps) for deploy-dev.yml (dev) - same
  pattern for dev images
- Remove build + base image pre-warm from NAS-side deploy jobs (image is
  now pre-loaded by the build job)
- deploy job condition: always() && build-image succeeded (so frontend
  test failure doesn't block deployment, but build failure does)

NAS HDD I/O was the bottleneck. VPS has SSD and same x86_64 arch.
This commit is contained in:
Gan, Jimmy
2026-06-04 17:49:43 +08:00
parent 03b515aa1d
commit 3c5ec3cdd2
2 changed files with 66 additions and 91 deletions
+32 -37
View File
@@ -157,10 +157,41 @@ jobs:
npm run test:coverage -- --reporter=verbose --run --pool=forks --poolOptions.forks.maxForks=2 || true
echo "Frontend tests completed (pre-existing Vite compatibility issues may cause failures)"
build-image-dev:
name: Build Dev Image
runs-on: vps
needs: [backend-tests]
steps:
- name: Checkout repository
run: |
if [ ! -d .git ]; then
git clone --depth=1 "http://100.78.131.124:3300/${GITHUB_REPOSITORY}.git" .
fi
- name: Build dev Docker image
run: |
set -e
echo "Building on VPS (SSD)..."
CACHE_ARG=""
if podman image exists nas-dashboard-dev:latest 2>/dev/null; then
CACHE_ARG="--cache-from nas-dashboard-dev:latest"
fi
podman build $CACHE_ARG -t nas-dashboard-dev:latest dashboard/
- name: Transfer image to NAS
run: |
set -e
echo "Streaming dev image to NAS..."
podman save nas-dashboard-dev:latest | ssh nasts "/volume1/@appstore/ContainerManager/usr/bin/docker load 2>&1"
echo "Retagging image..."
ssh nasts "/volume1/@appstore/ContainerManager/usr/bin/docker tag localhost/nas-dashboard-dev:latest nas-dashboard-dev:latest 2>&1 && /volume1/@appstore/ContainerManager/usr/bin/docker image rm localhost/nas-dashboard-dev:latest 2>&1"
echo "Dev image transferred and retagged successfully"
deploy-dev:
name: Deploy to Dev
runs-on: ubuntu-latest
needs: [backend-tests, frontend-tests]
needs: [build-image-dev, frontend-tests]
env:
SECRET_KEY: test-secret-key-for-ci-environment-32chars-minimum
container:
@@ -175,42 +206,6 @@ jobs:
git clone --depth=1 "http://gitea:3000/${GITHUB_REPOSITORY}.git" .
fi
- name: Warm mirror cache for base images
run: |
set -u
mirror_host="100.78.131.124:5501"
prewarm_base_image() {
image_ref="$1"
if docker image inspect "${image_ref}" >/dev/null 2>&1; then
echo "Image ${image_ref} already exists locally, skipping pre-pull"
return 0
fi
mirror_ref="${mirror_host}/library/${image_ref}"
echo "Attempting mirror pre-pull: ${mirror_ref}"
if timeout 30 docker pull "${mirror_ref}" 2>/dev/null; then
docker tag "${mirror_ref}" "${image_ref}"
echo "Mirror pre-pull succeeded for ${image_ref}"
else
echo "Mirror pre-pull failed for ${image_ref}, will pull during build"
fi
}
prewarm_base_image "node:20-alpine"
prewarm_base_image "python:3.12-slim"
- name: Build dev image
run: |
set -e
export DOCKER_API_VERSION=1.43
if ! DOCKER_BUILDKIT=0 docker build --cache-from nas-dashboard-dev:latest -t nas-dashboard-dev:latest dashboard/; then
echo "Build failed. Checking for network issues..."
curl -I https://registry.npmmirror.com || echo "npmmirror unreachable"
curl -I https://pypi.tuna.tsinghua.edu.cn || echo "Tsinghua PyPI unreachable"
exit 1
fi
- name: Sync runtime compose file
run: |
mkdir -p /volume1/docker/nas-dashboard
+34 -54
View File
@@ -168,11 +168,43 @@ jobs:
fi
echo "✅ Frontend tests passed"
build-image:
name: Build Docker Image
runs-on: vps
needs: [backend-tests]
steps:
- name: Checkout repository
run: |
if [ ! -d .git ]; then
git clone --depth=1 "http://100.78.131.124:3300/${GITHUB_REPOSITORY}.git" .
fi
- name: Build Docker image
run: |
set -e
echo "Building on VPS (SSD)..."
CACHE_ARG=""
if podman image exists nas-dashboard:latest 2>/dev/null; then
CACHE_ARG="--cache-from nas-dashboard:latest"
fi
podman build $CACHE_ARG -t nas-dashboard:latest dashboard/
- name: Transfer image to NAS
run: |
set -e
echo "Streaming image to NAS..."
podman save nas-dashboard:latest | ssh nasts "/volume1/@appstore/ContainerManager/usr/bin/docker load 2>&1"
echo "Retagging image..."
ssh nasts "/volume1/@appstore/ContainerManager/usr/bin/docker tag localhost/nas-dashboard:latest nas-dashboard:latest 2>&1 && /volume1/@appstore/ContainerManager/usr/bin/docker image rm localhost/nas-dashboard:latest 2>&1"
echo "Image transferred and retagged successfully"
deploy:
name: Deploy to Production
runs-on: nas
if: always()
needs: [backend-tests, frontend-tests]
if: always() && needs.build-image.result == 'success'
needs: [build-image, frontend-tests]
env:
SECRET_KEY: test-secret-key-for-ci-environment-32chars-minimum
GITEA_DB_PASSWORD: nyM3P4v1aYAsT7zfUtdguImNVHgFltCKCY/OjzWZVRE=
@@ -188,58 +220,6 @@ jobs:
git clone --depth=1 "http://gitea:3000/${GITHUB_REPOSITORY}.git" .
fi
- name: Warm mirror cache for base images
run: |
set -u
mirror_host="100.78.131.124:5501"
if command -v curl >/dev/null 2>&1; then
if curl -fsS --max-time 10 "http://${mirror_host}/v2/" >/dev/null; then
echo "Registry mirror is healthy at ${mirror_host}"
else
echo "Warning: registry mirror health check failed at ${mirror_host}; continuing with normal pull path"
fi
else
echo "Warning: curl is unavailable; skipping explicit mirror health check"
fi
prewarm_base_image() {
image_ref="$1"
# Skip if image already exists locally
if docker image inspect "${image_ref}" >/dev/null 2>&1; then
echo "Image ${image_ref} already exists locally, skipping pre-pull"
return 0
fi
mirror_ref="${mirror_host}/library/${image_ref}"
echo "Attempting mirror pre-pull: ${mirror_ref}"
if timeout 120 docker pull "${mirror_ref}"; then
docker tag "${mirror_ref}" "${image_ref}"
echo "Mirror pre-pull succeeded for ${image_ref}"
else
echo "Warning: mirror pre-pull failed for ${image_ref}; continuing with normal pull during build"
fi
}
prewarm_base_image "node:20-alpine"
prewarm_base_image "python:3.12-slim"
- name: Build
run: |
set -e
export DOCKER_API_VERSION=1.43
# DOCKER_BUILDKIT=0 is required for Synology ContainerManager's Docker daemon,
# which does not support BuildKit syntax. Remove when Synology updates to a
# Docker Engine version with full BuildKit support (currently 24.x, needs 23+).
# --cache-to type=inline is a no-op while BuildKit is disabled; it activates
# automatically when DOCKER_BUILDKIT=0 is removed.
if ! DOCKER_BUILDKIT=0 docker build --cache-from nas-dashboard:latest -t nas-dashboard:latest dashboard/; then
echo "Build failed. Checking for network issues..."
curl -I https://registry.npmmirror.com || echo "npmmirror unreachable"
curl -I https://pypi.tuna.tsinghua.edu.cn || echo "Tsinghua PyPI unreachable"
exit 1
fi
- name: Sync runtime compose file
run: |
mkdir -p /nas-dashboard