fix(ci): change deploy job to vps runner, route Docker commands via ssh nasts
Deploy Dashboard (Dev) / Backend Tests (push) Successful in 1m20s
Deploy Dashboard (Dev) / Frontend Tests (push) Successful in 1m1s
Deploy Dashboard (Dev) / Deploy to Dev (push) Has been cancelled
Deploy Dashboard (Dev) / Build Dev Image (push) Has been cancelled

This commit is contained in:
Gan, Jimmy
2026-06-07 11:57:46 +08:00
parent 59dd8ae1e2
commit 5c5ae99e79
+25 -28
View File
@@ -190,15 +190,10 @@ jobs:
deploy-dev: deploy-dev:
name: Deploy to Dev name: Deploy to Dev
runs-on: ubuntu-latest runs-on: vps
needs: [build-image-dev, 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:
volumes:
- /var/packages/ContainerManager/target/usr/bin/docker:/usr/bin/docker
- /var/packages/ContainerManager/target/usr/bin/docker-compose:/usr/lib/docker/cli-plugins/docker-compose
- /volume1/docker/nas-dashboard:/volume1/docker/nas-dashboard
steps: steps:
- name: Checkout repository - name: Checkout repository
run: | run: |
@@ -219,41 +214,44 @@ jobs:
GITEA_DB_PASSWORD: ${{ secrets.GITEA_DB_PASSWORD }} GITEA_DB_PASSWORD: ${{ secrets.GITEA_DB_PASSWORD }}
run: | run: |
set -u set -u
export DOCKER_API_VERSION=1.43 DOCKER="ssh nasts /volume1/@appstore/ContainerManager/usr/bin/docker"
COMPOSE="ssh nasts /volume1/@appstore/ContainerManager/usr/bin/docker-compose"
NAS_VOL="/volume1/docker/nas-dashboard"
cd /volume1/docker/nas-dashboard # Sync compose file to NAS
ssh nasts "mkdir -p $NAS_VOL"
scp dashboard/docker-compose.dev.yml "nasts:$NAS_VOL/docker-compose.dev.yml"
# Stop existing container if running # Stop existing container if running
docker compose -f docker-compose.dev.yml -p nas-dashboard-dev down || true $COMPOSE -f docker-compose.dev.yml -p nas-dashboard-dev down 2>/dev/null || true
# Ensure network exists (create only if it doesn't exist) # Ensure network exists (create only if it doesn't exist)
if ! docker network inspect nas-dashboard_internal >/dev/null 2>&1; then if ! $DOCKER network inspect nas-dashboard_internal >/dev/null 2>&1; then
docker network create nas-dashboard_internal $DOCKER network create nas-dashboard_internal
fi fi
# Use environment variables directly in compose or via command injection # Deploy
# For development, we can inject env vars into the compose run ssh nasts "cd $NAS_VOL && GITEA_TOKEN=$GITEA_TOKEN SECRET_KEY=$SECRET_KEY /volume1/@appstore/ContainerManager/usr/bin/docker-compose -f docker-compose.dev.yml -p nas-dashboard-dev up -d --pull never" 2>&1 || true
GITEA_TOKEN=$GITEA_TOKEN SECRET_KEY=$SECRET_KEY \
docker compose -f docker-compose.dev.yml -p nas-dashboard-dev up -d --pull never 2>&1 || true
if ! docker container inspect nas-dashboard-dev >/dev/null 2>&1; then if ! $DOCKER container inspect nas-dashboard-dev >/dev/null 2>&1; then
echo "Compose failed to create container..." echo "Compose failed to create container..."
exit 1 exit 1
fi fi
# Connect networks after container is created (idempotent) # Connect networks after container is created (idempotent)
docker network connect nas-dashboard_internal nas-dashboard-dev 2>/dev/null || true $DOCKER network connect nas-dashboard_internal nas-dashboard-dev 2>/dev/null || true
docker network connect gitea_gitea nas-dashboard-dev 2>/dev/null || true $DOCKER network connect gitea_gitea nas-dashboard-dev 2>/dev/null || true
# Verify both connections # Verify both connections
echo "=== Network connections ===" echo "=== Network connections ==="
docker inspect nas-dashboard-dev --format '{{json .NetworkSettings.Networks}}' | python3 -c 'import json,sys;nets=json.load(sys.stdin);[print(f" Connected to {n}") for n in nets];assert "nas-dashboard_internal" in nets and "gitea_gitea" in nets, "Missing required network";print("All network connections established")' $DOCKER inspect nas-dashboard-dev --format '{{json .NetworkSettings.Networks}}' | python3 -c 'import json,sys;nets=json.load(sys.stdin);[print(f" Connected to {n}") for n in nets];assert "nas-dashboard_internal" in nets and "gitea_gitea" in nets, "Missing required network";print("All network connections established")'
- name: Wait for container to be healthy - name: Wait for container to be healthy
run: | run: |
DOCKER="ssh nasts /volume1/@appstore/ContainerManager/usr/bin/docker"
echo "Waiting for container to be healthy..." echo "Waiting for container to be healthy..."
for i in {1..30}; do for i in {1..30}; do
STATUS=$(docker inspect --format='{{.State.Health.Status}}' nas-dashboard-dev 2>/dev/null || echo "starting") STATUS=$($DOCKER inspect --format='{{.State.Health.Status}}' nas-dashboard-dev 2>/dev/null || echo "starting")
if [ "$STATUS" = "healthy" ]; then if [ "$STATUS" = "healthy" ]; then
echo "✅ Container is healthy" echo "✅ Container is healthy"
break break
@@ -261,28 +259,29 @@ jobs:
echo "Waiting... ($i/30) Status: $STATUS" echo "Waiting... ($i/30) Status: $STATUS"
sleep 2 sleep 2
done done
STATUS=$(docker inspect --format='{{.State.Health.Status}}' nas-dashboard-dev 2>/dev/null || echo "unknown") STATUS=$($DOCKER inspect --format='{{.State.Health.Status}}' nas-dashboard-dev 2>/dev/null || echo "unknown")
if [ "$STATUS" != "healthy" ]; then if [ "$STATUS" != "healthy" ]; then
echo "❌ Container failed to become healthy: $STATUS" echo "❌ Container failed to become healthy: $STATUS"
docker logs nas-dashboard-dev --tail 50 $DOCKER logs nas-dashboard-dev --tail 50
exit 1 exit 1
fi fi
- name: Run smoke tests - name: Run smoke tests
run: | run: |
DOCKER="ssh nasts /volume1/@appstore/ContainerManager/usr/bin/docker"
echo "=== Running smoke tests via docker exec ===" echo "=== Running smoke tests via docker exec ==="
# Test 1: Health check # Test 1: Health check
echo "1. Testing health endpoint..." echo "1. Testing health endpoint..."
docker exec nas-dashboard-dev python3 -c "import urllib.request,json; d=json.loads(urllib.request.urlopen('http://localhost:4000/api/health',timeout=5).read()); assert d['status']=='ok', f'unexpected: {d}'" && echo "✅ Health check passed" || { echo "❌ Health check failed"; docker logs nas-dashboard-dev --tail 50; exit 1; } $DOCKER exec nas-dashboard-dev python3 -c "import urllib.request,json; d=json.loads(urllib.request.urlopen('http://localhost:4000/api/health',timeout=5).read()); assert d['status']=='ok', f'unexpected: {d}'" && echo "✅ Health check passed" || { echo "❌ Health check failed"; $DOCKER logs nas-dashboard-dev --tail 50; exit 1; }
# Test 2: Frontend loads # Test 2: Frontend loads
echo "2. Testing frontend loads..." echo "2. Testing frontend loads..."
docker exec nas-dashboard-dev python3 -c "import urllib.request; html=urllib.request.urlopen('http://localhost:4000/',timeout=5).read().decode(); assert 'NAS Dashboard' in html, f'missing NAS Dashboard'" && echo "✅ Frontend loads" || { echo "❌ Frontend failed to load"; exit 1; } $DOCKER exec nas-dashboard-dev python3 -c "import urllib.request; html=urllib.request.urlopen('http://localhost:4000/',timeout=5).read().decode(); assert 'NAS Dashboard' in html, f'missing NAS Dashboard'" && echo "✅ Frontend loads" || { echo "❌ Frontend failed to load"; exit 1; }
# Test 3: API endpoints require auth # Test 3: API endpoints require auth
echo "3. Testing API endpoints require auth..." echo "3. Testing API endpoints require auth..."
docker exec nas-dashboard-dev python3 -c " $DOCKER exec nas-dashboard-dev python3 -c "
import urllib.request, json import urllib.request, json
try: try:
resp = urllib.request.urlopen('http://localhost:4000/api/conversations/dates', timeout=5) resp = urllib.request.urlopen('http://localhost:4000/api/conversations/dates', timeout=5)
@@ -294,7 +293,7 @@ jobs:
# Test 4: Double /api/ prefix bug (non-failing) # Test 4: Double /api/ prefix bug (non-failing)
echo "4. Testing for double /api/ prefix bug..." echo "4. Testing for double /api/ prefix bug..."
docker exec nas-dashboard-dev python3 -c " $DOCKER exec nas-dashboard-dev python3 -c "
import urllib.request import urllib.request
try: try:
urllib.request.urlopen('http://localhost:4000/api/api/conversations/dates', timeout=5) urllib.request.urlopen('http://localhost:4000/api/api/conversations/dates', timeout=5)
@@ -304,7 +303,5 @@ jobs:
print('OK: /api/api/ returned 404') print('OK: /api/api/ returned 404')
" && echo "✅ No double /api/ prefix bug" || echo "⚠️ Double API prefix warning" " && echo "✅ No double /api/ prefix bug" || echo "⚠️ Double API prefix warning"
# Test 5: Container health already verified in previous step
echo "" echo ""
echo "=== All smoke tests passed! ===" echo "=== All smoke tests passed! ==="