Change : UI/UX design
This commit is contained in:
@@ -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 "========================================="
|
||||
Reference in New Issue
Block a user