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