Change : UI/UX design

This commit is contained in:
2026-06-21 18:56:18 +01:00
parent b43c87de73
commit ae267a6d9b
6 changed files with 765 additions and 276 deletions

View File

@@ -158,6 +158,55 @@ container_is_healthy() {
return 1
}
# --------------------------------------------------
# NEW: Detect a crash-looping Postgres container and
# attempt automatic recovery via pg_resetwal if the
# logs show WAL/checkpoint corruption. This is a safety
# net — the real fix is that backups now stop DB
# containers before tar'ing their volumes — but this
# protects against older/already-corrupt backups too.
# --------------------------------------------------
repair_postgres_if_crashlooping() {
local ctr="$1"
local vol="$2"
[ -z "$ctr" ] || [ -z "$vol" ] && return 0
docker ps -a --format '{{.Names}}' | grep -qx "$ctr" || return 0
sleep 8 # give it a moment to attempt startup
local restart_count status
restart_count=$(docker inspect --format='{{.RestartCount}}' "$ctr" 2>/dev/null || echo 0)
status=$(docker inspect --format='{{.State.Status}}' "$ctr" 2>/dev/null || echo "missing")
if [ "$status" = "restarting" ] || [ "$restart_count" -gt 2 ]; then
echo " ⚠️ $ctr is crash-looping (status=$status, restarts=$restart_count)"
local last_log
last_log=$(docker logs "$ctr" --tail 30 2>&1)
if echo "$last_log" | grep -qi "could not locate a valid checkpoint record\|invalid primary checkpoint\|unexpected pageaddr"; then
echo " 🔧 Detected WAL corruption — attempting pg_resetwal recovery on volume '$vol'..."
docker stop "$ctr" &>/dev/null || true
docker run --rm -v "${vol}:/var/lib/postgresql/data" postgres:15 \
bash -c "chown -R postgres:postgres /var/lib/postgresql/data && \
su postgres -c 'pg_resetwal -f /var/lib/postgresql/data'" \
&& echo " ✅ pg_resetwal completed" \
|| echo " ❌ pg_resetwal failed — manual intervention needed"
docker start "$ctr" &>/dev/null || true
sleep 8
status=$(docker inspect --format='{{.State.Status}}' "$ctr" 2>/dev/null || echo "missing")
if [ "$status" = "running" ]; then
echo "$ctr recovered and running (note: pg_resetwal can drop the most recent transactions — verify your data)"
else
echo "$ctr still not healthy after pg_resetwal — check 'docker logs $ctr' manually. DATA MAY BE LOST."
fi
else
echo "$ctr crash-looping for a reason other than WAL corruption — check 'docker logs $ctr' manually."
fi
fi
}
# --------------------------------------------------
# STEP 1: Restore Volumes
# --------------------------------------------------
@@ -259,6 +308,14 @@ declare -A APP_KEY=(
["n8n"]="n8n"
)
# Postgres-backed apps: map app key -> "container:volume" for the
# crash-loop auto-repair check run right after each app starts.
declare -A APP_POSTGRES=(
["n8n"]="n8n-postgres:n8n-setup_n8n-db-data"
["nextcloud"]="nextcloud-postgres:nextcloud-setup_nextcloud-db-data"
["odoo"]="odoo-clean-db-1:odoo-clean_db-data"
)
if [ -d "$SCRIPT_DIR/compose-files" ]; then
cd "$SCRIPT_DIR/compose-files"
for app in Frappe Odoo Nextcloud Mautic n8n; do
@@ -292,6 +349,14 @@ if [ -d "$SCRIPT_DIR/compose-files" ]; then
fi
docker-compose up -d 2>&1 | tail -3
cd ..
# If this app has a Postgres DB, check it didn't come up crash-looping.
pg_spec="${APP_POSTGRES[$app_key]:-}"
if [ -n "$pg_spec" ]; then
pg_ctr="${pg_spec%%:*}"
pg_vol="${pg_spec##*:}"
repair_postgres_if_crashlooping "$pg_ctr" "$pg_vol"
fi
done
cd "$SCRIPT_DIR"
else
@@ -475,7 +540,15 @@ else
docker start n8n-app 2>/dev/null && echo " ✅ Started n8n-app" || echo " ⚠️ Could not start n8n"
fi
fi
echo " ✅ n8n → http://${VM_IP}:5678"
# Re-check postgres after this section's potential restart too.
repair_postgres_if_crashlooping "n8n-postgres" "n8n-setup_n8n-db-data"
if container_is_healthy n8n-postgres; then
echo " ✅ n8n → http://${VM_IP}:5678"
else
echo " ⚠️ n8n-app is up but n8n-postgres is NOT healthy — check: docker logs n8n-postgres"
fi
fi
# --------------------------------------------------
@@ -485,9 +558,19 @@ echo ""
echo "========================================="
echo "✅ RESTORE COMPLETE"
echo "========================================="
if app_selected nextcloud; then echo " Nextcloud → http://${VM_IP}:8082"; fi
if app_selected mautic; then echo " Mautic → http://${VM_IP}:8081/s/login (admin / Admin!Password123)"; fi
if app_selected odoo; then echo " Odoo → https://odooo.nav.ovh/web"; fi
if app_selected n8n; then echo " n8n → http://${VM_IP}:5678"; fi
if app_selected frappe; then echo " Frappe → http://${VM_IP}:8080"; fi
summarize_app() {
local label="$1" url="$2" db_ctr="$3"
if [ -n "$db_ctr" ] && ! container_is_healthy "$db_ctr"; then
echo " ${label} → ⚠️ DB NOT healthy ($db_ctr) — check: docker logs $db_ctr"
else
echo " ${label}${url}"
fi
}
if app_selected nextcloud; then summarize_app "Nextcloud" "http://${VM_IP}:8082" "nextcloud-postgres"; fi
if app_selected mautic; then summarize_app "Mautic " "http://${VM_IP}:8081/s/login (admin / Admin!Password123)" "mautic-mariadb"; fi
if app_selected odoo; then summarize_app "Odoo " "https://odooo.nav.ovh/web" "odoo-clean-db-1"; fi
if app_selected n8n; then summarize_app "n8n " "http://${VM_IP}:5678" "n8n-postgres"; fi
if app_selected frappe; then summarize_app "Frappe " "http://${VM_IP}:8080" "frappe-mariadb"; fi
echo "========================================="