리눅스·서버 학습

Jenkins로 nginx 설정까지 안전하게 자동 배포하기

설정 오류가 나면 이전 상태로 자동 복구하는 배포 단계를 구성한 방법입니다.

애플리케이션 배포는 자동으로 해두고 nginx 설정만 서버에서 손으로 고치면, 저장소와 서버의 내용이 어긋납니다. 어느 쪽이 진짜인지 모르게 되고 재구축할 때 설정을 잃기 쉽습니다. 설정 파일도 저장소에서 관리하고 배포 때 함께 반영하도록 바꿨습니다.

위험한 점

nginx 설정에 오타가 있는 채로 재시작하면 사이트 전체가 내려갑니다. 그래서 복사, 검사, 적용, 복구 순서를 지켜야 합니다.

배포 단계

SITE=/etc/nginx/sites-available/default
BACKUP=$SITE.bak-jenkins

if sudo cmp -s nginx/site.conf "$SITE"; then
  echo "변경 없음"
else
  sudo cp "$SITE" "$BACKUP"
  sudo cp nginx/site.conf "$SITE"
  if sudo nginx -t; then
    sudo systemctl reload nginx
  else
    sudo cp "$BACKUP" "$SITE"
    sudo nginx -t && sudo systemctl reload nginx
    exit 1
  fi
fi

cmp로 변경이 없으면 건너뛰고, nginx -t가 실패하면 백업을 되돌린 뒤 빌드를 실패 처리합니다. 사이트는 이전 설정으로 계속 동작합니다.

reload를 쓰는 이유

reload는 새 워커를 띄우고 기존 연결은 끝날 때까지 유지합니다. 문법이 틀리면 기존 프로세스가 그대로 남기 때문에 재시작보다 안전합니다.

문법 검사로는 못 잡는 것

nginx -t는 문법만 봅니다. 리다이렉트나 캐시 헤더가 의도대로인지는 알려주지 않습니다. 중요한 변경은 다른 포트에 임시 인스턴스를 띄워 실제 요청으로 시험합니다.

nginx -t -c /tmp/test/nginx.conf -p /tmp/test
nginx -c /tmp/test/nginx.conf -p /tmp/test
curl -sI http://127.0.0.1:18999/tools/json

sudo 권한은 좁게

Jenkins 계정에 모든 sudo를 주면 빌드 스크립트가 서버 전체를 다룰 수 있습니다. 가능하면 필요한 명령만 sudoers에 지정합니다.

비밀값 다루기

  • 비밀번호와 키는 저장소가 아니라 Jenkins Credentials에 둡니다.
  • 셸 trace가 켜져 있으면 값이 로그에 찍힐 수 있으니 해당 구간에서 끕니다.
  • docker run에는 변수 이름만 넘겨 프로세스 목록에 값이 드러나지 않게 합니다.

nginx 설정 생성기