summaryrefslogtreecommitdiff
path: root/scripts/stop-debug.sh
diff options
context:
space:
mode:
Diffstat (limited to 'scripts/stop-debug.sh')
-rwxr-xr-xscripts/stop-debug.sh66
1 files changed, 49 insertions, 17 deletions
diff --git a/scripts/stop-debug.sh b/scripts/stop-debug.sh
index 43de07d..661d7c1 100755
--- a/scripts/stop-debug.sh
+++ b/scripts/stop-debug.sh
@@ -5,31 +5,63 @@ set -euo pipefail
script_dir="$(cd -- "$(dirname -- "${BASH_SOURCE[0]}")" && pwd)"
repo_dir="$(cd -- "$script_dir/.." && pwd)"
env_file="${AIGW_DEBUG_ENV_FILE:-$repo_dir/.env.debug}"
+stop_timeout="${AIGW_DEBUG_STOP_TIMEOUT:-30}"
-command -v docker >/dev/null 2>&1 || {
- printf '[aigw-debug] error: docker is not installed\n' >&2
+log() {
+ printf '[aigw-debug] %s\n' "$*"
+}
+
+fail() {
+ printf '[aigw-debug] error: %s\n' "$*" >&2
exit 1
}
+command -v docker >/dev/null 2>&1 || fail "docker is not installed"
+docker info >/dev/null 2>&1 || fail "cannot access Docker; check that the daemon is running and your user belongs to the docker group"
+
+if [[ ! "$stop_timeout" =~ ^[0-9]+$ ]]; then
+ fail "AIGW_DEBUG_STOP_TIMEOUT must be a non-negative integer"
+fi
+
+compose=(docker compose --project-directory "$repo_dir")
+if [[ -n "${AIGW_COMPOSE_PROJECT_NAME:-}" ]]; then
+ compose+=(--project-name "$AIGW_COMPOSE_PROJECT_NAME")
+fi
+
if [[ -f "$env_file" ]]; then
- compose=(docker compose --env-file "$env_file")
+ compose+=(--env-file "$env_file")
else
- export AIGW_SERVER_ADDRESS=:8080
- export AIGW_POSTGRES_USER=debug-stop-placeholder
- export AIGW_POSTGRES_PASSWORD=debug-stop-placeholder
- export AIGW_POSTGRES_DB=debug-stop-placeholder
- export AIGW_DATABASE_URL_DOCKER=postgres://debug-stop-placeholder:debug-stop-placeholder@postgres:5432/debug-stop-placeholder
- export AIGW_REDIS_URL_DOCKER=
+ # Compose still interpolates required variables for `down`; these values are
+ # only used to resolve the file and are never sent to a running service.
export AIGW_CREDENTIAL_KEY=debug-stop-placeholder
export AIGW_ADMIN_TOKEN=debug-stop-placeholder
- export AIGW_STRIPE_API_KEY=debug-stop-placeholder
- export AIGW_STRIPE_WEBHOOK_SECRET=debug-stop-placeholder
- export AIGW_STRIPE_SUCCESS_URL=http://127.0.0.1:8080/admin/?topup=success
- export AIGW_STRIPE_CANCEL_URL=http://127.0.0.1:8080/admin/?topup=cancel
- compose=(docker compose)
fi
cd "$repo_dir"
-printf '[aigw-debug] stopping services\n'
-"${compose[@]}" down --remove-orphans
-printf '[aigw-debug] stopped; PostgreSQL and Redis volumes were preserved\n'
+log "stopping all Compose services"
+down_status=0
+if "${compose[@]}" down --remove-orphans --timeout "$stop_timeout"; then
+ :
+else
+ down_status=$?
+fi
+
+# A forced cleanup handles containers left behind by an interrupted `down` or
+# by a previous compose configuration, while leaving named data volumes intact.
+mapfile -t remaining_containers < <("${compose[@]}" ps -aq 2>/dev/null || true)
+if ((${#remaining_containers[@]} > 0)); then
+ log "removing ${#remaining_containers[@]} remaining service container(s)"
+ if ! docker rm -f -- "${remaining_containers[@]}"; then
+ fail "could not remove all remaining service containers"
+ fi
+fi
+
+mapfile -t remaining_containers < <("${compose[@]}" ps -aq 2>/dev/null || true)
+if ((${#remaining_containers[@]} > 0)); then
+ fail "${#remaining_containers[@]} service container(s) are still running or present"
+fi
+if ((down_status != 0)); then
+ fail "docker compose down failed with exit code $down_status"
+fi
+
+log "all services stopped; named PostgreSQL and Redis volumes were preserved"