#!/usr/bin/env bash set -Eeuo pipefail ROOT="$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)" SRC="${ROOT}/stacks/haproxy" LIVE="/srv/nfs/infra/haproxy" ENV_FILE="${LIVE}/.env" BACKUP_ROOT="/srv/nfs/infra/.deploy-backups/haproxy" STAMP="$(date '+%Y%m%d-%H%M%S')" BACKUP="${BACKUP_ROOT}/${STAMP}" echo "=== HAProxy deployment ===" # # 1. Pre-deployment validation # "${ROOT}/scripts/validate-haproxy.sh" # # 2. Backup current configuration # echo echo "--- Backup current configuration ---" mkdir -p "${BACKUP}/conf" cp -a \ "${LIVE}/docker-compose.yml" \ "${BACKUP}/docker-compose.yml" rsync -a \ "${LIVE}/conf/" \ "${BACKUP}/conf/" echo "Backup: ${BACKUP}" # # Rollback function # rollback() { rc=$? echo echo "!!! Deployment failed" echo "!!! Restoring ${BACKUP}" cp -a \ "${BACKUP}/docker-compose.yml" \ "${LIVE}/docker-compose.yml" rsync -a --delete \ "${BACKUP}/conf/" \ "${LIVE}/conf/" ( cd "${LIVE}" docker compose \ --env-file "${ENV_FILE}" \ up -d --remove-orphans || true docker compose \ --env-file "${ENV_FILE}" \ restart haproxy || true ) exit "${rc}" } trap rollback ERR # # 3. Deploy files # echo echo "--- Deploy configuration ---" install \ -m 0644 \ "${SRC}/docker-compose.yml" \ "${LIVE}/docker-compose.yml" rsync -a --delete \ "${SRC}/conf/" \ "${LIVE}/conf/" # # 4. Apply Docker Compose # echo echo "--- Apply Docker Compose ---" cd "${LIVE}" docker compose \ --env-file "${ENV_FILE}" \ up -d --remove-orphans # # HAProxy config is bind-mounted. # docker compose will not automatically restart HAProxy # just because haproxy.cfg changed. # echo echo "--- Restart HAProxy ---" docker compose \ --env-file "${ENV_FILE}" \ restart haproxy # # 5. Post-deployment validation # sleep 2 RUNNING="$( docker inspect \ -f '{{.State.Running}}' \ haproxy )" if [[ "${RUNNING}" != "true" ]]; then echo "ERROR: HAProxy container is not running" exit 1 fi docker exec \ haproxy \ haproxy \ -c \ -f /usr/local/etc/haproxy/haproxy.cfg trap - ERR echo echo "=== Deployment successful ===" echo "Backup: ${BACKUP}"