From ad011b2db80b250c3ba4668b3aefcdf84c9e4aa8 Mon Sep 17 00:00:00 2001 From: Claude Date: Tue, 11 Aug 2026 03:24:50 +0000 Subject: [PATCH] Add check_container_health helper, wired into mattermost.sh as reference MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit A service's "Started" message after docker compose up -d doesn't mean the app is actually working — it can still crash-loop (bad DB password, missing required env var, etc.) with no visible sign until someone separately runs docker ps -a much later, exactly what happened repeatedly this session (mattermost, koha-db, homebox, vaultwarden, filebrowser all showed a clean "Started" message while crash-looping). check_container_health (lib/common.sh) waits briefly, checks the container's actual status and restart count via docker inspect, and prints recent logs automatically if it's not running or has already restarted — instead of a misleading one-line success message. Wired into mattermost.sh's own start step as the reference implementation, guarded by declare -F so standalone runs (no lib/common.sh sourced) degrade gracefully. Not retrofitted across every other service in one pass — this establishes the shared helper so other services can adopt it incrementally. Co-Authored-By: Claude Sonnet 5 Claude-Session: https://claude.ai/code/session_01H4k6J1qXXyYxhGEgnJaMvn --- lib/common.sh | 43 ++++++++++++++++++++++++++++++++++++++++++ services/mattermost.sh | 16 +++++++++++++--- 2 files changed, 56 insertions(+), 3 deletions(-) diff --git a/lib/common.sh b/lib/common.sh index 34aa245..b8e54d4 100644 --- a/lib/common.sh +++ b/lib/common.sh @@ -434,6 +434,49 @@ ensure_docker_dir_ownership() { done } +# Waits briefly after a container starts, then reports whether it's +# actually running or stuck restarting/crash-looping — printing recent +# logs on failure instead of leaving a silent "started" message that +# doesn't reflect whether it's actually working. Confirmed live: +# several services' own "Started"-looking `docker compose up -d` +# success message meant nothing — the container was already +# crash-looping by the time that message printed, with no indication +# anything was wrong until someone separately ran `docker ps -a` much +# later and had to go dig through logs by hand. +# +# Usage: check_container_health CONTAINER_NAME [WAIT_SECONDS] +# Returns 0 if the container is up and hasn't restarted, 1 otherwise. +check_container_health() { + local container="$1" wait_seconds="${2:-8}" + [ "$DRY_RUN" = true ] && return 0 + + sleep "$wait_seconds" + + local status + status="$(docker inspect -f '{{.State.Status}}' "$container" 2>/dev/null)" + if [ -z "$status" ]; then + log_warning "Container '$container' doesn't exist — something failed before it could even be created." + return 1 + fi + + local restart_count + restart_count="$(docker inspect -f '{{.RestartCount}}' "$container" 2>/dev/null || echo 0)" + + if [ "$status" = "running" ] && [ "$restart_count" -eq 0 ]; then + return 0 + fi + + if [ "$status" = "running" ]; then + log_warning "Container '$container' is running now but already restarted $restart_count time(s) — check the logs below." + else + log_warning "Container '$container' is not running (status: $status) — recent logs:" + fi + echo "" + docker logs "$container" --tail 20 2>&1 | sed 's/^/ /' + echo "" + return 1 +} + # Generate a secure alphanumeric password (no special characters) generate_password() { local length="${1:-32}" diff --git a/services/mattermost.sh b/services/mattermost.sh index 224e887..67363fd 100644 --- a/services/mattermost.sh +++ b/services/mattermost.sh @@ -742,9 +742,19 @@ MIGRATE_BODY local START="" prompt_yn "Start Mattermost now? (y/n):" "y" START if [ "$START" = "y" ] || [ "$START" = "Y" ]; then - docker compose up -d \ - && log_success "Mattermost started" \ - || log_warning "Start failed — check: docker compose logs" + if docker compose up -d; then + log_success "Mattermost started" + # Reference implementation of the shared health check — a + # "Started" message alone doesn't mean the app is actually up; + # it can still crash-loop (bad DB password, missing required + # env var, etc.) with no visible sign until someone separately + # runs `docker ps -a` much later. Mattermost's own first DB + # connection attempt can take a few seconds, hence the longer + # wait than check_container_health's 8s default. + declare -F check_container_health >/dev/null 2>&1 && check_container_health "$MM_CONTAINER" 12 + else + log_warning "Start failed — check: docker compose logs" + fi fi echo ""