Deploy-Fix: composer install + privates NIC im cloud-init

Zwei Bugs, die den ersten Live-Deploy lahmlegten:
1. composer install fehlte → vendor/ (gitignored, /app gemountet) fehlte →
   Symfony bootete nicht (autoload_runtime.php missing), Migrationen/Seed
   fielen durch. Jetzt: composer install --no-dev im php-Container nach up.
2. Hetzner-Privatnetz-NIC kam auf einem Node nicht hoch → DB unerreichbar
   (/health degraded). Jetzt: privates Interface defensiv per DHCP hochziehen
   und auf 10.x-IP warten, bevor migriert wird.

Manuell auf den Live-Nodes bereits nachgezogen; dieser Fix macht Re-Deploys
reproduzierbar.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
Thomas Peterson 2026-06-04 18:43:45 +02:00
parent eaa5c506de
commit 03355f89f3

View File

@ -54,9 +54,21 @@ write_files:
# SPA bauen (Profil-/QR-Links zeigen auf die öffentliche Domain) # SPA bauen (Profil-/QR-Links zeigen auf die öffentliche Domain)
docker run --rm -e VITE_PUBLIC_BASE="https://$DOMAIN" -v "$PWD/frontend":/app -w /app node:25-alpine sh -c "npm ci && npm run build" docker run --rm -e VITE_PUBLIC_BASE="https://$DOMAIN" -v "$PWD/frontend":/app -w /app node:25-alpine sh -c "npm ci && npm run build"
chown -R 1000:1000 /opt/vcard4 chown -R 1000:1000 /opt/vcard4
# Hetzner-Privatnetz-NIC (nicht eth0) sicher per DHCP hochziehen (für DB-Zugriff).
# Manchmal kommt das private Interface beim ersten Boot nicht hoch → DB unerreichbar.
PRIV=$(ls /sys/class/net | grep -E '^(enp|ens)' | grep -v '^eth0$' | head -1 || true)
if [ -n "${PRIV:-}" ] && ! ip -4 addr show "$PRIV" | grep -q 'inet 10\.'; then
printf '[Match]\nName=%s\n[Network]\nDHCP=ipv4\n' "$PRIV" > "/etc/systemd/network/10-$PRIV.network"
ip link set "$PRIV" up || true
systemctl restart systemd-networkd || true
for i in $(seq 1 30); do ip -4 addr | grep -q 'inet 10\.' && break; sleep 2; done
fi
COMPOSE="docker compose --project-directory /opt/vcard4 -f deploy/compose/docker-compose.prod.yml" COMPOSE="docker compose --project-directory /opt/vcard4 -f deploy/compose/docker-compose.prod.yml"
$COMPOSE up -d --build $COMPOSE up -d --build
sleep 20 sleep 20
# PHP-Abhängigkeiten installieren: vendor/ ist gitignored und /app ist als Volume
# gemountet (überdeckt ein im Image gebautes vendor) → hier in den Container hinein.
$COMPOSE exec -T -e COMPOSER_HOME=/tmp/composer php composer install --no-dev --optimize-autoloader --no-interaction --no-scripts
if [ "$RUN_MIGRATIONS" = "true" ]; then if [ "$RUN_MIGRATIONS" = "true" ]; then
$COMPOSE exec -T php php bin/console doctrine:migrations:migrate --no-interaction || true $COMPOSE exec -T php php bin/console doctrine:migrations:migrate --no-interaction || true
# Erst-Befüllung (idempotent: überspringt, wenn admin@vcard4reseller.de existiert) # Erst-Befüllung (idempotent: überspringt, wenn admin@vcard4reseller.de existiert)