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
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:
@@ -157,10 +157,41 @@ jobs:
|
|||||||
npm run test:coverage -- --reporter=verbose --run --pool=forks --poolOptions.forks.maxForks=2 || true
|
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)"
|
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:
|
deploy-dev:
|
||||||
name: Deploy to Dev
|
name: Deploy to Dev
|
||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
needs: [backend-tests, frontend-tests]
|
needs: [build-image-dev, frontend-tests]
|
||||||
env:
|
env:
|
||||||
SECRET_KEY: test-secret-key-for-ci-environment-32chars-minimum
|
SECRET_KEY: test-secret-key-for-ci-environment-32chars-minimum
|
||||||
container:
|
container:
|
||||||
@@ -175,42 +206,6 @@ jobs:
|
|||||||
git clone --depth=1 "http://gitea:3000/${GITHUB_REPOSITORY}.git" .
|
git clone --depth=1 "http://gitea:3000/${GITHUB_REPOSITORY}.git" .
|
||||||
fi
|
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
|
- name: Sync runtime compose file
|
||||||
run: |
|
run: |
|
||||||
mkdir -p /volume1/docker/nas-dashboard
|
mkdir -p /volume1/docker/nas-dashboard
|
||||||
|
|||||||
+34
-54
@@ -168,11 +168,43 @@ jobs:
|
|||||||
fi
|
fi
|
||||||
echo "✅ Frontend tests passed"
|
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:
|
deploy:
|
||||||
name: Deploy to Production
|
name: Deploy to Production
|
||||||
runs-on: nas
|
runs-on: nas
|
||||||
if: always()
|
if: always() && needs.build-image.result == 'success'
|
||||||
needs: [backend-tests, frontend-tests]
|
needs: [build-image, frontend-tests]
|
||||||
env:
|
env:
|
||||||
SECRET_KEY: test-secret-key-for-ci-environment-32chars-minimum
|
SECRET_KEY: test-secret-key-for-ci-environment-32chars-minimum
|
||||||
GITEA_DB_PASSWORD: nyM3P4v1aYAsT7zfUtdguImNVHgFltCKCY/OjzWZVRE=
|
GITEA_DB_PASSWORD: nyM3P4v1aYAsT7zfUtdguImNVHgFltCKCY/OjzWZVRE=
|
||||||
@@ -188,58 +220,6 @@ jobs:
|
|||||||
git clone --depth=1 "http://gitea:3000/${GITHUB_REPOSITORY}.git" .
|
git clone --depth=1 "http://gitea:3000/${GITHUB_REPOSITORY}.git" .
|
||||||
fi
|
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
|
- name: Sync runtime compose file
|
||||||
run: |
|
run: |
|
||||||
mkdir -p /nas-dashboard
|
mkdir -p /nas-dashboard
|
||||||
|
|||||||
Reference in New Issue
Block a user