#!/usr/bin/env bash # scripts/stop-services.sh — graceful stop + record the previous image SHA so # `./scripts/deploy.sh --rollback` can find a target. set -euo pipefail SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" . "$SCRIPT_DIR/_lib.sh" usage() { cat <<'EOF' Usage: ./scripts/stop-services.sh [--help] Reads from the environment: DEPLOY_CONTAINER_NAME name of the container to stop REGISTRY_TAG (optional, for logging only) Side-effect: writes scripts/.previous_tags.env containing PREVIOUS_SHA_TAG so the next deploy can roll back to whatever was running just before this stop. EOF } [[ "${1:-}" == "--help" || "${1:-}" == "-h" ]] && { usage; exit 0; } require_env DEPLOY_CONTAINER_NAME require_cmd docker PREV_FILE="$SCRIPT_DIR/.previous_tags.env" if container_exists "$DEPLOY_CONTAINER_NAME"; then REVISION="$(current_image_revision "$DEPLOY_CONTAINER_NAME")" if [[ -n "$REVISION" ]]; then SHA12="$(echo "$REVISION" | cut -c1-12)" SUFFIX="${REGISTRY_TAG##*-}" # arm / amd; falls back to whatever follows the last dash PREV_TAG="${SHA12}-${SUFFIX:-arm}" printf 'PREVIOUS_SHA_TAG=%s\nPREVIOUS_REVISION=%s\nRECORDED_AT=%s\n' \ "$PREV_TAG" "$REVISION" "$(date -u +%Y-%m-%dT%H:%M:%SZ)" > "$PREV_FILE" log_info "Recorded rollback target → $PREV_TAG (revision $REVISION) in $PREV_FILE" else log_warn "Could not read org.opencontainers.image.revision from $DEPLOY_CONTAINER_NAME — rollback target NOT recorded" fi if container_running "$DEPLOY_CONTAINER_NAME"; then # 40s matches the grace period in deployment_procedures.md §1; the app # itself shuts down after ShutdownTimeout=30s leaving 10s headroom. log_info "Stopping $DEPLOY_CONTAINER_NAME (grace 40s)" docker stop -t 40 "$DEPLOY_CONTAINER_NAME" else log_info "$DEPLOY_CONTAINER_NAME exists but is not running" fi log_info "Removing container $DEPLOY_CONTAINER_NAME" docker rm -f "$DEPLOY_CONTAINER_NAME" else log_info "$DEPLOY_CONTAINER_NAME does not exist — nothing to stop" fi