fix: apply Docker 24 network workaround and smoke tests to production deploy
- Add SECRET_KEY env to deploy job for compose variable expansion - Replace simple docker compose up with network stripping workaround (Docker 24 compose fails on external networks during container creation) - Connect containers to networks manually after compose creates them - Add smoke tests via docker exec against localhost:4000 - Create internal network manually when compose skips it Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
This commit is contained in:
@@ -171,6 +171,8 @@ jobs:
|
||||
name: Deploy to Production
|
||||
runs-on: ubuntu-latest
|
||||
needs: [backend-tests, frontend-tests]
|
||||
env:
|
||||
SECRET_KEY: test-secret-key-for-ci-environment-32chars-minimum
|
||||
container:
|
||||
volumes:
|
||||
- /var/packages/ContainerManager/target/usr/bin/docker:/usr/bin/docker
|
||||
@@ -237,24 +239,82 @@ jobs:
|
||||
- name: Sync runtime compose file
|
||||
run: cp dashboard/docker-compose.yml /nas-dashboard/docker-compose.yml
|
||||
|
||||
- name: Deploy
|
||||
- name: Deploy and verify
|
||||
run: |
|
||||
set -e
|
||||
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
|
||||
run: |
|
||||
# Docker 24 compose fails when it can't connect external networks
|
||||
# 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..."
|
||||
for i in {1..30}; do
|
||||
STATUS=$(docker inspect --format='{{.State.Health.Status}}' nas-dashboard 2>/dev/null || echo "starting")
|
||||
if [ "$STATUS" = "healthy" ]; then
|
||||
echo "✅ Container is healthy"
|
||||
exit 0
|
||||
break
|
||||
fi
|
||||
echo "Waiting... ($i/30) Status: $STATUS"
|
||||
sleep 2
|
||||
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
|
||||
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