리버스 프록시는 Caddy로 — Nginx를 안 쓴 이유
웹 서비스 앞단엔 보통 Nginx를 둡니다. 거의 업계 기본값입니다. 그런데 저는 Caddy를 골랐습니다. Nginx가 못해서가 아닙니다. 1인 개발에서 “기본값”보다 더 중요한 건, 설정 한 줄 한 줄에 내 시간을 얼마나 쓰느냐였습니다. 이 글은 “리버스 프록시가 뭔지”부터 “왜 자동 HTTPS 하나가 도구 선택을 갈랐는지”까지, 처음 보는 분도 따라올 수 있게 풀어 쓴 기록입니다.
리버스 프록시가 대체 뭔가
섹션 제목: “리버스 프록시가 대체 뭔가”용어부터 풀겠습니다. 한 대의 서버 위에 여러 프로그램이 동시에 떠 있습니다. 화면을 그리는 프론트(포털)가 한 자리, 데이터를 처리하는 백엔드 API가 다른 자리에서 돕니다. 이들은 각자 다른 “포트 번호”로 구분됩니다 — 같은 건물의 다른 호실이라고 보면 됩니다.
그래서 앞단에 프록시를 한 대 두고, 들어오는 요청을 보고 적절한 프로그램으로 분배하는 역할이 필요했습니다. 동시에 또 하나 중요한 일이 있습니다 — **HTTPS(보안 접속)**도 이 앞단에서 처리해야 합니다.
Nginx의 무게 — 못해서가 아니라 손이 많이 가서
섹션 제목: “Nginx의 무게 — 못해서가 아니라 손이 많이 가서”분명히 하겠습니다. Nginx는 강력하고 빠르고, 수십 년간 검증된 도구입니다. 거대한 트래픽을 받는 곳이라면 두말할 것 없는 선택입니다. 다만 1인 개발자가 직접 굴리기엔 챙길 게 적지 않습니다.
- HTTPS가 수동 — 인증서를 발급받고, 갱신해 주는 별도 도구를 붙이고, 그 갱신이 조용히 끊기지 않게 계속 지켜봐야 합니다.
- 설정이 장황 — 라우팅 규칙 하나를 바꾸려 해도 여러 줄의 설정 블록을 한참 들여다봐야 합니다. 6개월 뒤의 내가 그 블록을 바로 이해하지 못할 위험이 있습니다.
평소엔 문제없습니다. 문제는 문제가 생겼을 때입니다. “이게 왜 안 되지”를 추적하는 시간이, 혼자 모든 걸 떠안은 1인 개발에선 뼈아픕니다. 도구를 고를 때 저는 “잘 돌 때의 성능”보다 “안 돌 때의 디버깅 비용”을 더 무겁게 봤습니다.
Caddy를 고른 이유 — 자동 HTTPS와 간결함
섹션 제목: “Caddy를 고른 이유 — 자동 HTTPS와 간결함”Caddy의 가장 큰 매력은 HTTPS가 자동이라는 점입니다. 도메인 이름만 설정에 적어 두면, 인증서 발급도 갱신도 알아서 합니다. 제가 신경 쓸 일이 통째로 사라집니다. “인증서 만료로 사이트가 경고를 띄우는” 사고가 구조적으로 일어나지 않습니다.
설정도 짧습니다. “이 주소로 들어오면 이 호실로 넘겨라”가 거의 한 줄로 끝납니다. 아래는 실제 값을 일반화한 예시입니다.
example.com { handle /api/* { reverse_proxy localhost:백엔드포트 } handle { reverse_proxy localhost:프론트포트 }}읽어 보면 의도가 그대로 보입니다. “/api/로 시작하면 백엔드로, 나머지는 전부 프론트로.” 별도 주석 없이도 라우팅 규칙이 한눈에 읽힙니다. 설계 결정 문서(ADR)에도 그 근거를 “자동 HTTPS와 간결한 설정으로 단일 서버 운영 부담을 줄인다”고 남겨 뒀습니다.
| 항목 | Nginx | Caddy |
|---|---|---|
| HTTPS 인증서 | 발급·갱신 도구 별도 구성 | 자동(도메인만 적으면 끝) |
| 설정 길이 | 장황 — 블록 여러 줄 | 간결 — 의도가 한눈에 |
| 초대형 트래픽·정교한 캐싱 | 성숙도·생태계 유리 | 일반적 용도엔 충분 |
| 1인·단일 서버 적합도 | 손이 많이 감 | 운영 부담 작음 |
한 가지 운영 주의점 — 설정 사본을 동기화하라
섹션 제목: “한 가지 운영 주의점 — 설정 사본을 동기화하라”어떤 프록시를 쓰든 잊지 말아야 할 함정이 하나 있습니다. 서버에 실제 적용된 설정 파일과, 코드 저장소에 보관하는 설정 사본을 항상 같게 유지해야 한다는 것입니다.
이게 어긋나면 가장 헷갈리는 종류의 버그가 생깁니다. 한쪽(서버)만 급하게 고쳐 두면, 당장은 잘 돌지만 다음에 저장소 사본을 기준으로 다시 배포하는 순간 그 수정이 사라져 “어제는 됐는데 오늘은 깨지는” 혼란이 옵니다. 실제로 임시로 포트 하나를 바꿀 때조차 관련된 곳을 동시에 점검하지 않으면, 한 곳에 옛 설정이 남아 “접속 거부”가 잔재처럼 따라다닙니다.
특히 포트 하나를 옮기는 것처럼 사소해 보이는 변경일수록 위험합니다. 그 포트는 보통 한 곳에만 적혀 있지 않고 여러 곳에 흩어져 있기 때문입니다 — 프록시 설정, 백엔드 설정, 그리고 프론트가 백엔드를 부르는 주소까지. 한 곳만 고치면 나머지가 옛 포트를 가리킨 채 “연결 거부”가 잔재처럼 남습니다. 그래서 변경 전에 “이 값이 어디어디에 적혀 있나”를 먼저 떠올리는 습관을 들였습니다.
| 설정을 바꿀 때 점검할 곳 | 빠뜨리면 생기는 증상 |
|---|---|
| 프록시 실설정(서버) ↔ 저장소 사본 | 재배포 시 수정이 사라져 “어제는 됐는데” |
| 백엔드가 실제로 듣는 포트 | 프록시가 빈 호실로 보내 502/연결 거부 |
| 프론트가 백엔드를 부르는 주소 | 화면은 뜨는데 데이터만 안 옴 |
표로 적어 두니 단순해 보이지만, 급할 때 머릿속으로만 하면 꼭 한 칸을 빠뜨립니다. “흩어진 같은 값”을 한 번에 점검하는 것 — 이게 프록시 운영에서 가장 자주 저를 구한 작은 규율이었습니다.
처음 고르는 사람에게
섹션 제목: “처음 고르는 사람에게”“업계가 다 Nginx 쓰니까 나도”는 충분한 이유가 아닙니다. 기본값은 대형 트래픽·전담 인프라 팀이라는 맥락에서 만들어진 기본값입니다. 내 맥락 — 혼자, 단일 서버, 자동 갱신이 절실 — 이 다르면 기본값도 다시 의심해 볼 만합니다. “이 도구의 설정을 6개월 뒤의 내가 바로 이해할 수 있는가”를 한 번 물어보면, 의외로 답이 또렷해집니다.
이 프록시가 앞단을 지키는 서버 자체의 이야기는 〈서버를 세 번 옮긴 이야기〉, 그 뒤의 배포 자동화는 〈배포 자동화의 후회〉로 이어집니다. 전체 그림은 〈사례연구: SL.AIMS〉에 있습니다.