9. 운영 자동화(검증→반영→스모크→롤백) “nginx-safe-reload”
2025. 12. 28. 21:08
TechNote · NGINX · 09

운영 자동화: nginx-safe-reload(검증→반영→스모크→롤백) 만들기

검증→반영→스모크→롤백을 자동화하는 nginx-safe-reload를 예시로, 안전한 운영 자동화 흐름을 정리해 드립니다.

이 글의 목표
NGINX 설정 변경은 “정답”보다 “절차”가 품질을 결정합니다.
그래서 이 글은 검증(nginx -t) → 리로드 → 스모크 테스트 → 실패 시 롤백
스크립트+systemd로 표준화하는 방법을 제공합니다.

1) 운영 원칙 5가지

  1. 반영 전에 반드시 문법 검사: nginx -t 없이는 배포 금지
  2. 리로드는 되도록 reload: restart는 최후
  3. 스모크 테스트는 최소 3개: /healthz, /, /api(또는 /oauth2/auth)
  4. 백업/롤백은 자동화: “사람 기억”에 의존하지 않기
  5. 변경 이력은 남긴다: /etc/nginx를 git 또는 스냅샷으로 관리

2) 구성도(그림)

nginx-safe-reload 자동화 파이프라인(개념도)
nginx-safe-reload 자동화 파이프라인(개념도)
1) Backup/etc/nginx → tar2) nginx -t문법 검사3) reload무중단 반영4) Smoke testhealthz / apiFail → Restore backup → reload → Alert사고가 “자동으로 멈추고 되돌아가게”

3) nginx-safe-reload.sh (롤백 포함) — 실전 스크립트

파일: /usr/local/sbin/nginx-safe-reload.sh

#!/usr/bin/env bash
set -euo pipefail

TS="$(date +%Y%m%d_%H%M%S)"
BACKUP_DIR="/var/backups/nginx"
BACKUP_TAR="${BACKUP_DIR}/nginx_${TS}.tar.gz"

# 스모크 테스트 URL(환경에 맞게 수정)
URL_HEALTH="https://127.0.0.1/healthz"
URL_HOME="https://127.0.0.1/"
URL_API="https://127.0.0.1/api/health"

mkdir -p "${BACKUP_DIR}"

log() { echo "[nginx-safe] $*"; }

smoke_test() {
  log "smoke: healthz"
  curl -kfsS "${URL_HEALTH}" >/dev/null

  log "smoke: home"
  curl -kfsSI "${URL_HOME}" | egrep -i 'HTTP/'

  log "smoke: api"
  curl -kfsS "${URL_API}" >/dev/null
}

rollback() {
  local tarfile="$1"
  log "ROLLBACK: restoring ${tarfile}"
  tar -xzf "${tarfile}" -C /
  log "nginx -t (after rollback)"
  nginx -t
  log "reload nginx (after rollback)"
  systemctl reload nginx
}

log "backup: /etc/nginx → ${BACKUP_TAR}"
tar -czf "${BACKUP_TAR}" /etc/nginx

log "nginx -t"
nginx -t

log "reload nginx"
systemctl reload nginx

log "smoke test"
set +e
smoke_test
RC=$?
set -e

if [ "${RC}" -ne 0 ]; then
  log "smoke FAILED (rc=${RC})"
  rollback "${BACKUP_TAR}"
  log "DONE: rolled back"
  exit 1
fi

log "DONE: reload successful"
실전 팁
/api/health 같은 엔드포인트가 없다면 “없애지 말고” 이번 기회에 만들어두는 걸 추천합니다.
운영 시스템은 결국 헬스체크 품질이 가동률을 좌우해요.

4) systemd로 “표준 명령” 만들기

운영팀에서 중요한 건 “누가 해도 동일한 결과”입니다.
스크립트를 systemd 서비스로 감싸면, 실행 기록/권한/감사가 깔끔해집니다.

4-1) 서비스 유닛

파일: /etc/systemd/system/nginx-safe-reload.service

[Unit]
Description=NGINX safe reload with smoke test and rollback
After=network.target

[Service]
Type=oneshot
ExecStart=/usr/local/sbin/nginx-safe-reload.sh

4-2) 실행

sudo systemctl daemon-reload
sudo systemctl start nginx-safe-reload.service
sudo systemctl status nginx-safe-reload.service --no-pager

5) 주기 점검(timer) + 알림으로 확장

실무에선 “배포”뿐 아니라 “매일 점검”도 중요합니다.
예: 매일 새벽 nginx -t + 핵심 URL 스모크 테스트를 돌리고, 실패 시 알림.

5-1) Timer(하루 1회)

파일: /etc/systemd/system/nginx-safe-reload.timer

[Unit]
Description=Daily NGINX smoke check

[Timer]
OnCalendar=*-*-* 04:10:00
Persistent=true

[Install]
WantedBy=timers.target

5-2) Timer 활성화

sudo systemctl daemon-reload
sudo systemctl enable --now nginx-safe-reload.timer
systemctl list-timers | grep nginx-safe
알림 확장(추천)
systemd 서비스 실패를 감지해서 n8n/Zabbix/Slack으로 알리는 구조로 확장하면,
“사람이 발견하기 전에” 시스템이 먼저 알려줍니다.

여기까지 하면 NGINX 운영이 “개인의 숙련도”가 아니라 “팀의 시스템”이 됩니다.