31단계배포가 멈출 때, 그리고 안전장치
배포는 생각보다 자주 멈춘다. 다행히 멈추는 곳은 대개 정해져 있다. 무엇을 묻지 않고 해도 되는지는 내가 정한다.
걸리는 시간 · 읽기 약 10분 · 따라 하기 약 45분 · 난이도 ★★★ 심화 · 화면 확인 2026.09.27
이 단계를 마치면
- 고쳤는데 주소가 그대로일 때 브랜치, 캐시, 설정·빌드 오류 순으로 원인을 가려낼 수 있다.
- "로컬에선 되는데 배포하면 안 된다"를 배포 로그, 환경변수, 마지막 배포 시각 순서로 확인할 수 있다.
- 인증키를 환경변수로 옮기고, 권한 설정으로 되돌리기 어려운 일은 반드시 확인을 거치게 할 수 있다.
고쳐서 푸시했다. 배포 목록도 확인했다. 그런데 팀장 휴대폰에는 여전히 어제 화면이 떠 있다. 도대체 어디서 막힌 걸까?
멈추는 세 곳. 고쳐서 푸시했는데 주소의 화면이 그대로라면 먼저 세 곳을 의심한다. 순서대로 살펴보면 대부분 여기서 원인이 잡힌다.
| 원인 | 알아보는 법 | 대처 |
|---|---|---|
| 다른 브랜치 | 배포 목록 맨 위에 새 배포가 없거나, 본 주소가 아닌 미리보기 주소로 배포됐다 | Claude에게 지금 어느 브랜치에 있는지 묻고, 본줄에 합치거나 본줄에서 다시 푸시한다 |
| 브라우저 캐시 | 배포 목록에는 새 배포가 준비됨인데 내 화면만 그대로다 | 강력 새로고침(윈도우 Ctrl+Shift+R, 맥 Cmd+Shift+R), 시크릿 창, 다른 기기로 열어 본다 |
| 설정·빌드 오류 | 배포 상태가 실패로 끝났다 | 실패한 배포를 열어 로그를 읽는다 |
캐시란 브라우저가 한 번 받은 파일을 기억해 두었다가 다시 쓰는 방식을 말한다. 평소에는 화면을 빠르게 열어 주지만, 방금 고친 내용을 가리기도 한다. 휴대폰은 특히 예전 파일을 오래 붙잡고 있을 때가 있다. 다른 기기나 시크릿 창에서 바뀐 화면이 보인다면 배포는 제대로 됐고, 내 브라우저만 늦었을 뿐이다.
로그는 겁먹지 말고 열자. 배포 목록에서 실패한 배포를 누르면 배포 과정이 줄줄이 적힌 기록이 나온다. 끝부분에 빨간 줄이나 "Error", "failed" 같은 말이 있는 곳이 원인에 가깝다. 코드를 몰라도 괜찮다. 로그를 통째로 복사해 Claude Code에 붙이고 원인과 고칠 계획을 물으면 된다. 다만 로그에 인증키 같은 값이 보이면 지우고 붙인다.
로컬에선 되는데 배포하면 안 될 때. 수업에서 가장 자주 들은 하소연이다. 내 노트북에서 index.html을 열면 잘 되는데, 주소로 열면 일부가 안 된다. 이럴 때는 순서를 정해 확인한다.
| 순서 | 볼 곳 | 흔한 원인 |
|---|---|---|
| 1 | 배포 로그와 실행 중 로그 | 파일을 못 찾는다는 오류. 내 노트북은 파일 이름의 대소문자를 가리지 않는데 배포 서버는 가리는 경우가 많다. Logo.png와 logo.png가 다른 파일이 된다 |
| 2 | 배포 서비스의 환경변수 목록 | 노트북에만 넣고 배포 서비스에는 넣지 않았다 |
| 3 | 마지막 배포 시각 | 환경변수를 넣은 뒤 다시 배포하지 않았다. 넣은 값은 대개 다음 배포부터 적용된다 |
이전 배포로 되돌리기. 새 배포를 올렸더니 화면이 깨졌다면, 원인을 찾기 전에 먼저 사람들이 쓰는 주소부터 살린다. Vercel과 Cloudflare Pages 모두 배포 목록에 지난 배포들이 남아 있고, 잘 돌던 배포를 골라 다시 본 주소로 올리는 되돌리기(Rollback) 기능이 있다. 되돌린 다음에 29단계의 방법으로 코드를 고치고, 미리보기 주소에서 확인한 뒤 다시 푸시한다. 순서를 거꾸로 하면 고치는 동안 동료들이 깨진 화면을 계속 보게 된다.
인증키는 환경변수로. 외부 데이터를 쓰는 도구라면 인증키 문제가 따라온다. 키를 화면 코드에 적으면 그 화면을 여는 사람 누구나 내 키를 가져갈 수 있다. 브라우저에서 페이지 코드를 들여다보는 일은 어렵지 않다. 게다가 저장소에 한 번 올라간 키는 지워도 기록에 남는다. 그래서 키는 코드 밖, 환경변수에 둔다. 환경변수는 코드와 따로 보관하는 설정 값이다. 노트북에서는 저장소에 올라가지 않는 별도 파일(흔히 .env.local)에, 배포 서비스에서는 설정 화면의 환경변수 항목에 넣는다. 저장소에는 이름만 적힌 예시 파일(.env.example)을 올려 두어, 이어받을 사람이 무엇을 넣어야 하는지 알게 한다.
환경변수에 넣었다고 끝난 것도 아니다. 화면 코드가 그 값을 직접 쓰면 결국 브라우저로 전달된다. 키가 필요한 요청은 서버 쪽 작은 함수가 대신 보내고, 화면은 그 함수에게서 결과만 받게 한다. 서비스마다 이런 함수를 두는 방법이 있다. Vercel은 api 폴더에 둔 파일이 곧 하나의 주소가 되는 방식을 쓴다. 구조 설계는 Claude에게 맡기되, "키가 브라우저로 가지 않게"를 조건으로 준다. 이미 키를 저장소에 올렸다면 지우는 것만으로는 부족하다. 그 키를 발급한 곳에서 폐기하고 새로 발급받는다.
무엇을 묻지 않고 해도 되는가. Claude Code는 기본적으로 파일을 고치거나 명령을 실행하기 전에 묻는다. 익숙해지면 같은 허락을 계속 누르다 지친다. 그러다 보면 읽지도 않고 누르게 되고, 그 순간 안전장치는 없는 것이나 마찬가지가 된다. 그래서 무엇은 묻지 않아도 되고 무엇은 반드시 물어야 하는지 미리 정해 둔다. 그 도구가 권한 모드다. 매번 묻는 기본 모드, 파일 편집은 묻지 않고 받아들이는 모드, 26단계의 플랜 모드처럼 읽기만 하는 모드가 있다. 모든 것을 묻지 않고 하게 하는 모드도 있지만, 망가져도 상관없는 격리된 환경에서나 쓸 일이다. 회사 노트북에서 켜 둘 모드는 결코 아니다. 모드와 별개로 설정 파일에 "이 명령은 묻지 않고 허락", "이 명령은 언제나 거절"을 적어 둘 수도 있다. Claude Code 안에서 /permissions를 치면 지금 적힌 목록을 보고 고칠 수 있다. 모드 이름과 설정 방법은 공식 문서에서 확인하자.
기준을 정하는 질문은 하나뿐이다. 이 일이 틀렸을 때 되돌릴 수 있는가?
| 일 | 되돌릴 수 있나 | 설정 |
|---|---|---|
| 파일 목록 보기, 파일 읽기 | 바꾸는 것이 없다 | 묻지 않게 해도 된다 |
| 파일 편집 | 커밋 기록이 있으면 되돌릴 수 있다 | 커밋 습관이 붙은 뒤 묻지 않게 해도 된다 |
| 파일 삭제, 강제로 덮어쓰기 | 되돌리기 어렵다 | 언제나 묻거나 막는다 |
| 메일 발송, 결제, 운영 중인 데이터 변경 | 되돌릴 수 없다 | 반드시 사람이 확인한다 |
한마디로 줄이면 이렇다. 읽기는 넓게, 쓰기는 좁게, 보내기는 확인 후에. 이 원칙은 뒤에서 회사 도구를 연결할 때(제7부)도 그대로 되풀이된다.
권한 설정만으로 막기 어려운 규칙도 있다. 어떤 규칙은 "꼭" 지켜져야 하고, 어떤 일은 다른 보조에게 나눠 맡기는 편이 낫다. 이런 경우를 위한 훅, 서브에이전트, MCP 같은 기능은 바로 다음 32단계에서 따로 다룬다.
현장 장면
배포한 다음 주, 윤 과장은 입력 항목 순서를 바꿔 푸시했다. 그런데 팀장이 휴대폰으로 열어 보니 예전 순서 그대로였다. 윤 과장은 배포 목록을 열었다. 맨 위에 새 배포가 있긴 했다. 다만 본 주소 대신 미리보기로 표시돼 있었다. Claude에게 지금 어느 브랜치에 있는지 묻자 답이 나왔다. 지난주 색 실험 때 만든 브랜치에 그대로 머물러 있었던 것이다. 본줄에 합치게 하자 본 주소로 새 배포가 돌았다. 그런데도 팀장 휴대폰은 여전히 예전 화면이었다. 시크릿 창으로 열자 새 순서가 보였다. 범인은 캐시였다.
다음 막힘은 날씨였다. 외근 계획에 참고하려고 공공데이터 서비스의 날씨 정보를 붙였는데, 노트북에서는 오늘 날씨가 보이고 주소에서는 "정보를 불러오지 못했습니다"만 떴다. 윤 과장은 표의 순서대로 따라갔다. 실행 중 로그에 인증키가 비어 있다는 오류가 있었다. 배포 서비스의 환경변수 목록을 열어 보니 텅 비어 있었다. 노트북의 .env.local에만 넣어 두었던 것이다. 환경변수 항목에 이름과 값을 넣고 마지막 배포 시각을 확인하니, 값을 넣기 전이었다. 다시 배포하자 날씨가 떴다.
그런데 그 과정에서 더 큰 구멍이 드러났다. 처음 날씨를 붙일 때 Claude가 만든 코드는 키를 화면 코드에서 바로 읽고 있었다. 저장소가 비공개라 눈에 띄지 않았을 뿐, 주소를 여는 누구나 브라우저에서 키를 볼 수 있는 상태였다. 등골이 서늘해지는 순간이었다. 윤 과장은 "키가 브라우저로 가지 않게 서버 쪽 함수로 옮기는 계획"을 요청해 고쳤고, 기존 키는 발급한 곳에서 폐기하고 새로 받았다. CLAUDE.md에도 "인증키는 환경변수로만 읽고, 화면 코드에서 직접 쓰지 않는다"를 추가했다. 권한 설정도 바꿨다. 파일 편집은 묻지 않게 하고, 파일 삭제와 강제 푸시는 언제나 묻게 했다.
따라 하기
- 문구 하나를 고쳐 푸시한 뒤, 배포 목록에서 새 배포가 본 주소로 나갔는지 확인한다. 성공 기준: 맨 위 배포가 본줄 기준이고 준비됨이다.
- 주소를 강력 새로고침, 시크릿 창, 다른 기기로 각각 열어 본다. 성공 기준: 세 경우 모두 고친 문구가 보인다.
- 지난 배포 중 실패한 것이 있으면 로그를 열고, 아래 첫 번째 프롬프트로 원인을 묻는다. 없으면 성공한 배포의 로그를 한 번 읽는다. 성공 기준: 로그의 어느 줄이 원인인지, 또는 어느 줄이 "완료"인지 가리킬 수 있다.
- 도구에 인증키가 쓰인다면 아래 두 번째 프롬프트로 환경변수와 서버 쪽 함수로 옮기고, 배포 서비스에 값을 넣은 뒤 다시 배포한다. 성공 기준: 저장소 어디에도 키 값이 없고, 주소에서 기능이 동작한다.
- Claude Code가 허락을 물었던 일을 적고 위 표로 나눈 뒤, 되돌릴 수 있는 일 하나를 묻지 않게, 되돌리기 어려운 일은 언제나 묻게 설정한다. 성공 기준: 삭제를 시켜 보면 여전히 허락을 묻는다.
복사해 쓰는 프롬프트
배포가 실패했어. 아래는 배포 로그야(인증키로 보이는 값은 지웠어).
[로그 붙여 넣기]
1. 원인이 된 줄을 찾아서, 무슨 뜻인지 우리말로 설명해 줘.
2. 내 노트북에서는 되는데 배포에서만 안 되는 이유가 있다면 알려 줘. 파일 이름 대소문자, 환경변수, 설정을 특히 봐 줘.
3. 고칠 계획만 먼저 보여 주고, 내가 좋다고 하면 고친 뒤 커밋해 줘.
이 도구에서 인증키를 쓰는 곳을 모두 찾아서 목록으로 보여 줘. 고치지는 말고 먼저 보고만.
그다음 이렇게 바꾸는 계획을 보여 줘.
- 키는 환경변수 [변수 이름]으로만 읽는다. 코드에 값을 적지 않는다.
- 키가 필요한 요청은 서버 쪽 함수가 보내고, 화면은 결과만 받는다. 키가 브라우저로 가지 않게 한다.
- 노트북용 값 파일은 저장소에 올라가지 않게 하고, 예시 파일에는 이름만 남긴다.
- 오류가 나면 원문 대신 우리말 한 문장만 화면에 보이게 한다.
배포 서비스에 무엇을 넣고 언제 다시 배포해야 하는지도 순서대로 적어 줘.
막히면 이렇게
| 증상 | 원인 | 처방 |
|---|---|---|
| 푸시했는데 본 주소가 그대로다 | 다른 브랜치에 올렸다 | 지금 브랜치를 확인하고 본줄에 합친다 |
| 배포는 준비됨인데 내 화면만 예전이다 | 브라우저 캐시 | 강력 새로고침, 시크릿 창, 다른 기기로 연다 |
| 노트북에선 되는데 주소에선 데이터가 안 뜬다 | 배포 서비스에 환경변수를 안 넣었거나 넣고 재배포를 안 했다 | 로그 → 환경변수 목록 → 마지막 배포 시각 순서로 보고, 넣은 뒤 다시 배포한다 |
| 키가 저장소나 화면 코드에 있었다 | 코드에 값을 직접 적었다 | 환경변수로 옮기고, 그 키는 폐기한 뒤 새로 발급한다 |
실습 파일
공개 저장소에 올려 둔 가공 자료와 양식이다. 회사 자료 대신 먼저 이것으로 해 본다.
- 채워 쓰는 양식 CLAUDE_예시.md · 내 작업 폴더에
CLAUDE.md로 이름을 바꿔 두는 규칙 파일 양식 - 채워 쓰는 양식 배포_전_점검표.md · 사내 도구를 주소로 올리기 전의 공개 범위·인증키·권한·열어 보기 점검
스스로 점검
- ☐ 화면이 그대로일 때 살펴볼 세 곳을 순서대로 말할 수 있는가
- ☐ 저장소와 화면 코드 어디에도 인증키 값이 없는가
- ☐ 파일 삭제와 강제 덮어쓰기는 여전히 허락을 묻게 되어 있는가
점검 해설 보기
- 화면이 그대로일 때 다른 브랜치, 브라우저 캐시, 설정·빌드 오류 순으로 본다고 말할 수 있으면 통과다. 로컬에서만 될 때 보는 순서(로그, 환경변수 목록, 마지막 배포 시각)와 섞이지 않게 구분한다. 「멈추는 세 곳」 표를 다시 본다.
- 두 번째 프롬프트로 찾게 했을 때 저장소와 화면 코드에서 키 값이 하나도 나오지 않고, 키가 필요한 요청은 서버 쪽 함수가 보내고 있으면 통과다. 한 번이라도 저장소에 올렸다면 지우는 것으로 끝내지 말고 발급한 곳에서 폐기하고 새로 받는다. 「인증키는 환경변수로」를 다시 읽는다.
- 파일 삭제를 시켜 봤을 때 여전히 허락을 묻는다면 통과다. 묻지 않고 지워진다면
/permissions에서 목록을 열어 삭제와 강제 덮어쓰기를 언제나 묻거나 막도록 고친다. 「무엇을 묻지 않고 해도 되는가」의 표를 다시 본다.
기억할 것
- 화면이 그대로면 브랜치, 캐시, 로그 순으로 본다. 로컬과 배포가 다르면 로그, 환경변수, 마지막 배포 시각 순으로 본다.
- 키는 환경변수에 두고 브라우저로 보내지 않는다. 되돌리기 어려운 일은 언제나 묻게 한다.
더 알아보기 · Vercel 즉시 되돌리기 · Vercel 환경변수 · Cloudflare Pages 되돌리기 · Cloudflare Pages 빌드 설정