fix: apply Docker 24 network workaround and smoke tests to production deploy #64
@@ -171,6 +171,8 @@ jobs:
|
|||||||
name: Deploy to Production
|
name: Deploy to Production
|
||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
needs: [backend-tests, frontend-tests]
|
needs: [backend-tests, frontend-tests]
|
||||||
|
env:
|
||||||
|
SECRET_KEY: test-secret-key-for-ci-environment-32chars-minimum
|
||||||
container:
|
container:
|
||||||
volumes:
|
volumes:
|
||||||
- /var/packages/ContainerManager/target/usr/bin/docker:/usr/bin/docker
|
- /var/packages/ContainerManager/target/usr/bin/docker:/usr/bin/docker
|
||||||
@@ -237,24 +239,82 @@ jobs:
|
|||||||
- name: Sync runtime compose file
|
- name: Sync runtime compose file
|
||||||
run: cp dashboard/docker-compose.yml /nas-dashboard/docker-compose.yml
|
run: cp dashboard/docker-compose.yml /nas-dashboard/docker-compose.yml
|
||||||
|
|
||||||
- name: Deploy
|
- name: Deploy and verify
|
||||||
run: |
|
run: |
|
||||||
set -e
|
set -e
|
||||||
export DOCKER_API_VERSION=1.43
|
export DOCKER_API_VERSION=1.43
|
||||||
docker compose -f /nas-dashboard/docker-compose.yml up -d --pull never
|
|
||||||
|
|
||||||
- name: Wait for container to be healthy
|
# Docker 24 compose fails when it can't connect external networks
|
||||||
run: |
|
# during container creation. Try compose first; if the container
|
||||||
|
# isn't created, strip networks from compose file and retry.
|
||||||
|
docker compose -f /nas-dashboard/docker-compose.yml up -d --pull never 2>&1 || true
|
||||||
|
|
||||||
|
if ! docker container inspect nas-dashboard >/dev/null 2>&1; then
|
||||||
|
echo "Compose failed to create container, stripping networks from compose file..."
|
||||||
|
python3 -c "
|
||||||
|
import os
|
||||||
|
lines = open('/nas-dashboard/docker-compose.yml').readlines()
|
||||||
|
out = []
|
||||||
|
skip_net = False
|
||||||
|
for l in lines:
|
||||||
|
stripped = l.strip()
|
||||||
|
if stripped == 'networks:' and not l[0].isspace():
|
||||||
|
skip_net = True
|
||||||
|
continue
|
||||||
|
if skip_net:
|
||||||
|
if l[0].isspace():
|
||||||
|
continue
|
||||||
|
skip_net = False
|
||||||
|
if stripped == 'networks:' and l[:4].strip() == '':
|
||||||
|
skip_net = True
|
||||||
|
continue
|
||||||
|
if skip_net:
|
||||||
|
if l.startswith(' '):
|
||||||
|
continue
|
||||||
|
skip_net = False
|
||||||
|
out.append(l)
|
||||||
|
open('/tmp/prod-ci.yml','w').writelines(out)
|
||||||
|
"
|
||||||
|
docker compose -f /tmp/prod-ci.yml up -d --pull never
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Create the internal network if compose didn't create it
|
||||||
|
docker network create internal 2>/dev/null || true
|
||||||
|
|
||||||
|
# Connect docker-socket-proxy to networks
|
||||||
|
docker network connect internal docker-socket-proxy 2>/dev/null || true
|
||||||
|
docker network connect nas-dashboard_internal docker-socket-proxy 2>/dev/null || true
|
||||||
|
|
||||||
|
# Connect dashboard to networks
|
||||||
|
docker network connect internal nas-dashboard 2>/dev/null || true
|
||||||
|
docker network connect nas-dashboard_internal nas-dashboard 2>/dev/null || true
|
||||||
|
docker network connect gitea_gitea nas-dashboard 2>/dev/null || true
|
||||||
|
|
||||||
|
# Verify network connections
|
||||||
|
echo "=== Network connections ==="
|
||||||
|
docker inspect nas-dashboard --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, "Missing nas-dashboard_internal";print("All network connections established")'
|
||||||
|
|
||||||
|
# Wait for container to be healthy
|
||||||
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 2>/dev/null || echo "starting")
|
STATUS=$(docker inspect --format='{{.State.Health.Status}}' nas-dashboard 2>/dev/null || echo "starting")
|
||||||
if [ "$STATUS" = "healthy" ]; then
|
if [ "$STATUS" = "healthy" ]; then
|
||||||
echo "✅ Container is healthy"
|
echo "✅ Container is healthy"
|
||||||
exit 0
|
break
|
||||||
fi
|
fi
|
||||||
echo "Waiting... ($i/30) Status: $STATUS"
|
echo "Waiting... ($i/30) Status: $STATUS"
|
||||||
sleep 2
|
sleep 2
|
||||||
done
|
done
|
||||||
echo "❌ Container failed to become healthy"
|
STATUS=$(docker inspect --format='{{.State.Health.Status}}' nas-dashboard 2>/dev/null || echo "unknown")
|
||||||
|
if [ "$STATUS" != "healthy" ]; then
|
||||||
|
echo "❌ Container failed to become healthy: $STATUS"
|
||||||
docker logs nas-dashboard --tail 50
|
docker logs nas-dashboard --tail 50
|
||||||
exit 1
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Run smoke tests via docker exec
|
||||||
|
echo "=== Running smoke tests ==="
|
||||||
|
docker exec nas-dashboard 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 --tail 50; exit 1; }
|
||||||
|
docker exec nas-dashboard 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; }
|
||||||
|
echo ""
|
||||||
|
echo "=== All deployment checks passed! ==="
|
||||||
|
|||||||
Reference in New Issue
Block a user