Nginx + GitHub Utterances 장애 복구기
어느 날 갑자기 블로그가 죽었다#
2026년 1월 29일 아침.
평소처럼 plzrun.com에 접속했는데 아예 사이트가 열리지 않았다.
404도 아니고, 일부 기능 고장도 아니고, 그냥 접속 자체가 안 되는 상태였다.
처음엔 “EC2가 죽었나?”, “디스크 찼나?” 같은 생각부터 들었다.
하지만 서버에 직접 접속해보니 EC2 자체는 살아 있었고, 문제는 Nginx였다.
1단계: 블로그 전체 장애 (Nginx 기동 실패)#
증상#
- plzrun.com 접속 불가
- Nginx 서비스가 계속 내려가 있음
- 수동 재시작도 실패
원인 로그#
journalctl -u nginx[emerg] host not found in upstream "api.github.com"
nginx: configuration file test failed👉 문제는 GitHub API를 upstream으로 지정한 설정이었다.
Nginx 설정 안에 아래와 같은 코드가 있었는데,
proxy_pass https://api.github.com/...이 설정은 Nginx 시작 시점에 DNS 해석이 안 되면, 서버 자체가 부팅 실패로 간주된다.
마침 그 시점에:
- unattended-upgrade가 실행 중이었고
- systemd-resolved / network 서비스가 재시작되는 타이밍과 겹치면서
api.github.comDNS 해석이 실패
👉 그 결과 Nginx 전체가 기동 불가 → 블로그 전체 다운
1단계 조치: Nginx를 다시 살리기#
여기서 가장 중요했던 조치 두 가지:
1) resolver 명시#
resolver 1.1.1.1 8.8.8.8 valid=300s ipv6=off;→ Nginx가 런타임에 DNS를 다시 해석할 수 있도록 변경
2) upstream을 변수 기반으로 변경#
set $github_api api.github.com;
proxy_pass https://$github_api;이렇게 바꾸자:
- DNS가 순간적으로 실패해도
- Nginx는 부팅 자체는 성공
- 블로그 메인 페이지 정상 복구
🎉 여기까지가 1차 복구.
👉 이제 블로그는 다시 열렸다.
그런데… 최신 댓글만 안 나온다?#
블로그는 열리는데, 좌측 사이드바에 있는 Utterances 기반 최신 댓글 위젯만 비어 있음을 발견했다.
- 본문 댓글은 정상
- 댓글 작성도 정상
- 최신 댓글 목록만 실패
이때부터는 전체 장애가 아니라 기능 장애였다.
2단계: 최신 댓글 위젯 장애#
구조 정리#
브라우저 → /api/github-comments/... → Nginx → GitHub API
문제의 JS 코드:
const issuesApi = "/api/github-comments/issues";
const commentsApi = "/api/github-comments/issues/{id}/comments";하지만 Nginx 설정을 보니…
proxy_pass https://api.github.com/repos/.../issues/comments;👉 경로를 고정해버린 상태
그래서:
/issues요청 ❌/issues/{id}/comments요청 ❌- 일부 curl 테스트만 우연히 성공
즉, JS가 기대하는 REST 구조와 Nginx가 프록시하는 구조가 불일치했다.
2단계 조치: GitHub API 그대로 프록시#
해결 방법은 아래와 같았다.
Nginx는 가공하지 말고 ‘관문’처럼만 두자. GitHub API는 그대로 통과시키는 게 제일 안전하다.
location /api/github-comments/ {
set $github_api api.github.com;
resolver 1.1.1.1 8.8.8.8 valid=300s ipv6=off;
proxy_ssl_server_name on;
proxy_set_header Host $github_api;
include /etc/nginx/conf.d/github-token.conf;
proxy_set_header Accept "application/vnd.github+json";
proxy_set_header User-Agent "plzrun-blog";
proxy_pass https://$github_api/repos/sency90/plzrun-blog-comments/;
proxy_connect_timeout 5s;
proxy_read_timeout 15s;
proxy_send_timeout 15s;
}결과:
/issues정상/issues/{id}/comments정상- 최신 댓글 위젯 즉시 복구
🎉 2차 복구 완료
진짜 원흉: Jenkins Agent 폭주#
추가로 로그를 보다가 소름 돋는 걸 발견했다.
jenkins-agent.service: restart counter is at 2082xxx- Jenkins agent가 무한 재시작
- systemd에 엄청난 부하
- unattended-upgrade + 네트워크 재시작과 겹침
👉 Jenkins agent 즉시 disable
sudo systemctl disable jenkins-agent
sudo systemctl stop jenkins-agent이후 서버 안정화.
정리#
장애 흐름 요약#
- unattended-upgrade + 네트워크 재시작
- DNS 해석 실패
- Nginx upstream 해석 실패 → 블로그 전체 다운
- resolver + 변수 기반 proxy_pass로 1차 복구
- 최신 댓글 위젯은 API 경로 불일치로 여전히 실패
- proxy_pass 구조 수정 → 기능 완전 복구
- Jenkins agent 폭주 발견 및 차단
교훈#
- ❌ Nginx에 외부 DNS upstream을 하드코딩하지 말 것
- ❌ systemd 서비스 무한 재시작 방치 금물
- ✅ reverse proxy는 “중계자”로만 두는 게 가장 안전
- ✅ 기능 장애와 전체 장애를 반드시 분리해서 생각할 것