diff --git a/docker/entrypoint.sh b/docker/entrypoint.sh index c5db388..07ddb5b 100644 --- a/docker/entrypoint.sh +++ b/docker/entrypoint.sh @@ -3,26 +3,100 @@ set -euo pipefail cd /var/www/html +# region agent log +fc_debug_log() { + local hypothesis="$1" + local message="$2" + local data_json="${3:-{}}" + local data_b64 + data_b64=$(printf '%s' "$data_json" | base64 | tr -d '\n') + FC_DEBUG_HYPOTHESIS="$hypothesis" FC_DEBUG_MESSAGE="$message" FC_DEBUG_DATA_B64="$data_b64" php -r ' + $json = base64_decode(getenv("FC_DEBUG_DATA_B64") ?: ""); + $data = json_decode($json, true); + if (!is_array($data) && str_ends_with($json, "}}")) { + $data = json_decode(substr($json, 0, -1), true); + } + $payload = [ + "sessionId" => "885d37", + "runId" => "coolify-bad-gateway", + "hypothesisId" => getenv("FC_DEBUG_HYPOTHESIS") ?: "", + "location" => "docker/entrypoint.sh", + "message" => getenv("FC_DEBUG_MESSAGE") ?: "", + "data" => [ + "raw_json" => $json, + "parsed" => is_array($data) ? $data : null, + ], + "timestamp" => (int) round(microtime(true) * 1000), + ]; + $line = json_encode($payload, JSON_UNESCAPED_SLASHES) . PHP_EOL; + @file_put_contents("/var/www/html/debug-885d37.log", $line, FILE_APPEND); + fwrite(STDERR, "agent_debug " . $line); + ' +} +# endregion + echo "[flixcooks] Waiting for database..." TRIES=0 MAX_TRIES="${DB_WAIT_MAX_TRIES:-30}" +start_data=$(php -r 'echo json_encode([ + "database_url_present" => getenv("DATABASE_URL") !== false && getenv("DATABASE_URL") !== "", + "run_db_seed" => getenv("RUN_DB_SEED") ?: "", + "db_wait_max_tries" => getenv("DB_WAIT_MAX_TRIES") ?: "30", + "entrypoint_args" => array_slice($argv, 1), + "schema_file_exists" => file_exists("/var/www/html/scripts/schema.sql"), + "seed_file_exists" => file_exists("/var/www/html/data/recipes.json"), +]);' -- "$@") +fc_debug_log "H1,H2,H4" "entrypoint started" "$start_data" -until php scripts/db-check.php >/dev/null 2>&1; do +until db_check_output=$(php scripts/db-check.php 2>&1); do TRIES=$((TRIES + 1)) + fail_data=$(php -r 'echo json_encode([ + "attempt" => (int) $argv[1], + "max_tries" => (int) $argv[2], + "db_check_output" => $argv[3], + ]);' -- "$TRIES" "$MAX_TRIES" "$db_check_output") + fc_debug_log "H1" "db-check failed while waiting" "$fail_data" if [ "$TRIES" -ge "$MAX_TRIES" ]; then echo "[flixcooks] Database not reachable after ${MAX_TRIES} attempts." >&2 + fc_debug_log "H1" "entrypoint exiting because database never became reachable" "$fail_data" exit 1 fi sleep 2 done +success_data=$(php -r 'echo json_encode([ + "attempts_before_success" => (int) $argv[1], + "db_check_output" => $argv[2], +]);' -- "$TRIES" "$db_check_output") +fc_debug_log "H1" "db-check succeeded" "$success_data" echo "[flixcooks] Applying schema..." -php -r "require 'helpers.php'; require_database(); echo \"schema ok\n\";" +if schema_output=$(php -r "require 'helpers.php'; require_database(); echo \"schema ok\n\";" 2>&1); then + schema_data=$(php -r 'echo json_encode(["schema_output" => $argv[1]]);' -- "$schema_output") + fc_debug_log "H2,H4" "schema apply succeeded" "$schema_data" +else + code=$? + schema_data=$(php -r 'echo json_encode(["exit_code" => (int) $argv[1], "schema_output" => $argv[2]]);' -- "$code" "$schema_output") + fc_debug_log "H2,H4" "schema apply failed, entrypoint exiting" "$schema_data" + echo "$schema_output" >&2 + exit "$code" +fi if [ "${RUN_DB_SEED:-false}" = "true" ]; then echo "[flixcooks] Seeding recipes from data/recipes.json..." - php scripts/db-seed.php + if seed_output=$(php scripts/db-seed.php 2>&1); then + seed_data=$(php -r 'echo json_encode(["seed_output" => $argv[1]]);' -- "$seed_output") + fc_debug_log "H4" "seed succeeded" "$seed_data" + else + code=$? + seed_data=$(php -r 'echo json_encode(["exit_code" => (int) $argv[1], "seed_output" => $argv[2]]);' -- "$code" "$seed_output") + fc_debug_log "H4" "seed failed, entrypoint exiting" "$seed_data" + echo "$seed_output" >&2 + exit "$code" + fi +else + fc_debug_log "H4" "seed skipped" '{"run_db_seed":"false"}' fi echo "[flixcooks] Starting Apache..." +fc_debug_log "H3" "executing web server command" "$(php -r 'echo json_encode(["command" => array_slice($argv, 1)]);' -- "$@")" exec "$@" diff --git a/docs/COOLIFY.md b/docs/COOLIFY.md index 5545c3d..f4cbf65 100644 --- a/docs/COOLIFY.md +++ b/docs/COOLIFY.md @@ -26,8 +26,8 @@ Die App startet **nicht**, wenn `DATABASE_URL` fehlt oder Postgres nicht erreich 1. Neues **Database** → PostgreSQL (16). 2. Notieren: - - Benutzer, Passwort, Datenbankname - - **Internal URL** (Host ist oft der Service-Name, z. B. `postgresql-xxxxx` oder was Coolify anzeigt) + - Benutzer, Passwort, Datenbankname + - **Internal URL** (Host ist oft der Service-Name, z. B. `postgresql-xxxxx` oder was Coolify anzeigt) 3. Format für die App: ```text @@ -50,22 +50,26 @@ postgresql://flixcooks:geheim@postgresql-flixcooks:5432/flixcooks 2. Dockerfile-Pfad: `Dockerfile` (Root). 3. Port: **80** (Container exponiert Apache auf 80). 4. Health Check (optional, empfohlen): - - Path: `/health.php` - - Erwartet HTTP 200 mit `{"status":"ok"}` + - Path: `/health.php` + - Erwartet HTTP 200 mit `{"status":"ok"}` ### Environment Variables (Pflicht) -| Variable | Beschreibung | -|----------|----------------| -| `DATABASE_URL` | Interne Postgres-URL von Coolify | + +| Variable | Beschreibung | +| --------------------- | --------------------------------- | +| `DATABASE_URL` | Interne Postgres-URL von Coolify | | `FLIXCOOKS_ADMIN_KEY` | Starkes Passwort für `/admin.php` | + ### Environment Variables (optional) -| Variable | Default | Beschreibung | -|----------|---------|----------------| -| `RUN_DB_SEED` | `false` | Einmalig `true` setzen → importiert `data/recipes.json` beim Start | -| `DB_WAIT_MAX_TRIES` | `30` | Warteversuche bis Postgres da ist (à 2 s) | + +| Variable | Default | Beschreibung | +| ------------------- | ------- | ------------------------------------------------------------------ | +| `RUN_DB_SEED` | `false` | Einmalig `true` setzen → importiert `data/recipes.json` beim Start | +| `DB_WAIT_MAX_TRIES` | `30` | Warteversuche bis Postgres da ist (à 2 s) | + Nach dem ersten erfolgreichen Deploy: `RUN_DB_SEED` wieder auf `false` oder entfernen. @@ -73,9 +77,11 @@ Nach dem ersten erfolgreichen Deploy: `RUN_DB_SEED` wieder auf `false` oder entf Mount für Impressum/Datenschutz (`data/site.json`): -| Mount Path (Container) | Inhalt | -|------------------------|--------| -| `/var/www/html/data` | `site.json` bleibt nach Redeploy erhalten | + +| Mount Path (Container) | Inhalt | +| ---------------------- | ----------------------------------------- | +| `/var/www/html/data` | `site.json` bleibt nach Redeploy erhalten | + Rezepte liegen in Postgres – **kein** Volume für Rezepte nötig. @@ -131,10 +137,13 @@ curl http://127.0.0.1:8080/health.php ## 7. Troubleshooting -| Problem | Lösung | -|---------|--------| -| Container startet nicht | Logs: DB nicht erreichbar → `DATABASE_URL` Host/Passwort prüfen | -| 503 „Datenbank nicht verfügbar“ | Gleiches Netzwerk in Coolify? Internal URL? | -| Leere Seite, Health OK | `RUN_DB_SEED=true` einmalig oder Admin-Rezepte anlegen | -| Admin geht nicht | `FLIXCOOKS_ADMIN_KEY` gesetzt? | -| `site.json` verloren nach Deploy | Volume auf `/var/www/html/data` mounten | + +| Problem | Lösung | +| -------------------------------- | --------------------------------------------------------------- | +| Container startet nicht | Logs: DB nicht erreichbar → `DATABASE_URL` Host/Passwort prüfen | +| 503 „Datenbank nicht verfügbar“ | Gleiches Netzwerk in Coolify? Internal URL? | +| Leere Seite, Health OK | `RUN_DB_SEED=true` einmalig oder Admin-Rezepte anlegen | +| Admin geht nicht | `FLIXCOOKS_ADMIN_KEY` gesetzt? | +| `site.json` verloren nach Deploy | Volume auf `/var/www/html/data` mounten | + +