diff --git a/deploy/install.sh b/deploy/install.sh index 3bdc169..7e2bc3e 100755 --- a/deploy/install.sh +++ b/deploy/install.sh @@ -275,7 +275,16 @@ else # inside the container belong to it and not to root. # Supplied through --env-file; skipped silently when absent, so a first # install can happen before the Stripe account exists. - optional_env() { [[ -n "${2:-}" ]] && set_env "$1" "$2"; } + # An `if`, not `[[ … ]] && …`: the && form makes the function return 1 for + # every value that is absent, and under `set -e` that ends the install. + # Absent is the NORMAL case here — these are the optional ones — so the + # script killed itself on the first installation that did not happen to + # supply a Hetzner token. + optional_env() { + if [[ -n "${2:-}" ]]; then + set_env "$1" "$2" + fi + } optional_env HETZNER_DNS_TOKEN "${HETZNER_DNS_TOKEN:-}" optional_env CLUPILOT_DNS_ZONE "${CLUPILOT_DNS_ZONE:-}" @@ -303,12 +312,23 @@ log "Building and starting the containers (this takes a few minutes)" compose build --quiet app compose up -d -log "Waiting for the application container" -for _ in $(seq 1 60); do - compose exec -T app php -v >/dev/null 2>&1 && break +# Not `php -v`: PHP answers within seconds, while the entrypoint is still +# running `composer install` on a fresh checkout — which takes minutes. The old +# condition let the migration below run against a checkout with no vendor/ at +# all, and artisan died on a missing autoload.php. Wait for what is actually +# needed, exactly as the dependent containers already do. +log "Waiting for the application container to install its dependencies" +deps_ready=0 +for _ in $(seq 1 180); do + if compose exec -T app test -f vendor/autoload.php 2>/dev/null; then + deps_ready=1 + break + fi sleep 5 done +[[ $deps_ready -eq 1 ]] || die "vendor/ never appeared. Look at: docker compose logs app" + log "Running migrations" compose exec -T app php artisan migrate --force