페이지 목차
이 페이지에서 검색
AI 드리븐
이 페이지에 묻기
AI 드리븐 · 현재 차시와 목차 본문에서만 찾아 답합니다. 답을 지어내지 않고 해당하는 대목을 그대로 보여 주며, 여기에 없으면 없다고 알려 드립니다.
생성형 AI가 아니라 이 페이지 본문을 찾아 그대로 보여 주는 방식입니다. 외부로 나가는 요청이 없습니다.
AI · DEVELOPMENT
AI 드리븐
생성 수정
요구사항과 역할 정의부터 구현·검증·배포·운영까지, AI와 함께 개발하며 사람이 판단할 기준을 정리합니다.
26개 문서 · 3일차 · 22 / 26
21차시 · 배포 ① 서버 공개
지도 위치 : 3일차 · 신뢰와 운영 · 로컬에서 원격으로 | 이전: 20차시 자동화 파이프라인 ② | 다음: 22차시 배포 ② 서비스 완성 키워드 : 서버를 인터넷에 배포, 비밀값의 안전한 관리, 배포 검증
이 차시를 다 읽으면
- 배포 를 유와 종차로 정의하고, 로컬과 배포 환경에서 달라지는 것 네 가지를 ④ 로컬 ↔ 원격 축으로 댈 수 있다.
- 코드가 인터넷에서 응답하기까지의 단계를 컨테이너 이미지 · PaaS 를 써서 순서대로 말할 수 있다.
- 비밀값 주입 을 정의하고, 이미지에 비밀값을 넣으면 왜 위험한지 설명할 수 있다.
- "배포 명령 성공"과 "서비스 정상"을 증거 ↔ 주장 축으로 가르고, 스모크 테스트 를 포함한 배포 검증 다섯 가지를 댈 수 있다.
- 롤백 을 정의하고, 18차시의 revert와 무엇이 다른지, 왜 DB 마이그레이션은 쉽게 되돌아가지 않는지 말할 수 있다.
0. 이 차시의 판별 축
| # | 축 | 왼쪽 (0) | 오른쪽 (1) | 이 축으로 갈리는 것 | 큰 축 (README 5장) |
|---|---|---|---|---|---|
| 1 | 내 컴퓨터인가, 인터넷 너머인가 | 로컬 서버 (localhost) | 배포된 서버 (공개 주소) | 환경변수 · 네트워크 · DB 주소 · 파일이 모두 달라짐 | ⭐ ④ 로컬 ↔ 원격 |
| 2 | 구워 넣나, 실행할 때 넣나 | 이미지 · 코드에 비밀값을 넣음 (영구히 남음) | 실행하는 순간 환경변수로 주입 (실행 중에만) | 이미지를 가진 사람이 키를 볼 수 있는가 | ① 디스크 ↔ 메모리 |
| 3 | 명령이 성공했나, 서비스가 정상인가 | "배포 성공" 메시지 | 헬스체크 · 스모크 테스트 결과 | 배포가 끝났다고 말할 근거 | 증거 ↔ 주장 (⑧의 파생) |
| 4 | 되돌릴 수 있는가 | 코드 배포 (롤백 버튼) | DB 마이그레이션 (쉽게 안 돌아옴) | 배포 단계를 나눌 곳 | 되돌릴 수 있는가 (①의 파생) |
이 차시가 답하는 질문은 "로컬에선 됐는데"가 가장 많이 나오는 단계를 어떻게 넘는가 입니다. 앞에서 배운 인프라 설정의 원칙 (15차시)과 비밀값 원칙 (14차시)이 처음으로 다른 컴퓨터 위에서 시험받습니다.
1. 배포 — 무엇에 속하는가
1.1 정의
배포 (deployment) — [소프트웨어 전달 단계]인데, [ 만든 프로그램을 다른 사람이 쓸 수 있는 원격 환경에 올려 실행시킨다 ]는 점에서 내 컴퓨터에서 돌려 보는 로컬 실행과 구별된다.
스테이징 (staging) — [배포 환경]인데, [ 운영과 같은 구성이지만 실제 사용자 · 실제 돈이 없는 시험장 ]이라는 점에서 실제 사용자가 쓰는 운영(production)과 구별된다.
환경변수 — 앞에서 배운 대로 (15차시), 프로그램이 실행될 때 바깥에서 받아 읽는 이름 = 값 설정 입니다. DB 주소나 키처럼 환경마다 다른 값을 코드 밖에 두는 통로입니다.
1.2 경계 — 로컬과 배포 환경에서 달라지는 것
| 로컬 | 배포 환경 | |
|---|---|---|
| 환경변수 | 내 컴퓨터의 .env 파일 | 플랫폼 설정 화면에 등록한 값 |
| 네트워크 | localhost, 나만 접속 | 공개 주소, HTTPS, 누구나 접속 |
| DB | 내 컴퓨터의 DB | 관리형 DB (앞에서 배운 아키텍처 결정, 8차시) |
| 파일 시스템 | 남아 있음 | 재시작하면 사라질 수 있음 (컨테이너는 대개 매번 새로 시작) |
⚠️ "로컬에선 됐는데"의 원인은 거의 이 네 줄 중 하나입니다. 19차시의 CI가 "깨끗한 환경"으로 일부를 미리 걸러 주지만, 실제 주소 · 실제 DB · 실제 비밀값은 배포해야 처음 만납니다.
1.3 반례 — 이건 배포가 아닙니다
| 대상 | 왜 아닌가 |
|---|---|
| 내 컴퓨터에서 서버를 켜고 같은 와이파이의 휴대폰으로 접속 | 원격 환경 이 아님. 내 컴퓨터가 꺼지면 같이 꺼짐 |
main에 병합한 것 | 코드가 공유됐을 뿐, 어디서도 실행되지 않음 (22차시에서 둘을 잇는다) |
| 배포 명령이 "성공"으로 끝난 것 | 올리는 과정이 끝났을 뿐. 서비스가 정상인지는 4절에서 확인 |
2. 서버를 인터넷에 올리는 흐름
2.1 흐름
코드 ─▶ 빌드 ─▶ 컨테이너 이미지 ─▶ 실행 플랫폼에 올림 ─▶ 주소 연결(도메인, HTTPS)
(Dockerfile, 15차시) │
├─ 환경변수 · 비밀값 주입 (3절)
├─ DB 연결 (관리형 DB, 8차시)
└─ 마이그레이션 실행 (12차시) (5.2절)
🔍 읽는 포인트 : 가운데의 컨테이너 이미지 가 "옮길 수 있는 덩어리"이고, 오른쪽 세 갈래가 배포 환경에서만 채워지는 것 입니다.
컨테이너 이미지 — [실행 꾸러미]인데, [ 프로그램과 그 실행 환경(언어 버전 · 라이브러리)을 한 파일로 묶어 어느 컴퓨터에서나 같게 돌게 한다 ]는 점에서 소스 코드만 담은 저장소와 구별된다. 앞에서 배운 Dockerfile (15차시)이 이 이미지를 만드는 설계도입니다.
2.2 실행 플랫폼
PaaS (Platform as a Service) — [실행 플랫폼]인데, [ 이미지나 코드만 주면 서버 관리 · HTTPS · 재시작을 플랫폼이 맡는다 ]는 점에서 운영체제부터 내가 관리하는 가상 서버와 구별된다.
| 실행 플랫폼 유형 | 예 | 특징 |
|---|---|---|
| ⭐ PaaS / 컨테이너 호스팅 | Render, Fly.io, Railway, Google Cloud Run, AWS App Runner | 이미지만 주면 실행 · HTTPS까지 처리. 입문에 적합 |
| 컨테이너 오케스트레이션 | AWS ECS, Kubernetes | 세밀한 제어, 운영 부담 큼 |
| 서버리스 함수 | AWS Lambda, Vercel Functions | 요청 단위 실행, 구조 제약 있음 |
(서비스별 기능과 가격은 바뀌므로 공식 문서 확인.)
배포 순서 : 스테이징에 먼저 → 확인(4절) → 운영. 운영 배포는 앞 차시에서 정한 대로 사람 승인 (20차시)입니다.
3. ⭐ 비밀값의 안전한 관리
3.1 정의와 경계
비밀값 주입 — [설정 전달 방식]인데, [ 비밀값을 코드와 이미지 밖에 두고, 프로그램을 실행하는 순간에만 환경변수로 넣는다 ]는 점에서 이미지나 설정 파일에 구워 넣는 방식과 구별된다.
앞에서 배운 비밀값 원칙 (14차시)을 배포 환경으로 확장합니다. 배포 순간 비밀값이 처음으로 다른 컴퓨터 에 넘어갑니다. 넘기는 방법이 잘못되면 유출됩니다.
❌ 코드에 직접 const key = "sk_live_abc..."
❌ Git에 올린 설정 파일 config.prod.json 안에 키
❌ 컨테이너 이미지 안 Dockerfile에서 ENV로 키를 박음
⭕ 플랫폼 비밀값 설정 실행할 때 환경변수로 주입
⭕ 비밀값 관리 서비스 AWS Secrets Manager, GCP Secret Manager 등에서 읽음
⭕ CI 비밀값 GitHub Secrets → 배포 단계에서만 사용
🔍 읽는 포인트 : ❌ 세 줄은 비밀값이 파일 안에 영구히 남는 방식, ⭕ 세 줄은 실행할 때만 건네는 방식입니다. 0절 축 2가 이 경계입니다.
⚠️ 이미지 안의 비밀값이 특히 위험한 이유 : 이미지는 옮기고 나누기 위한 파일입니다. 이미지에 넣은 환경변수는 docker inspect 같은 명령으로 이미지를 받은 누구나 꺼내 볼 수 있습니다. 앞에서 배운 대로 (18차시) Git 이력에 남은 키처럼, 한번 퍼진 이미지에서 키를 지울 방법은 없고 키 교체 만 남습니다.
3.2 네 가지 원칙
| 원칙 | 의미 |
|---|---|
| 최소 권한 | 서버 계정은 필요한 비밀값만 읽을 수 있음 |
| 환경별 분리 | 스테이징과 운영은 다른 키 · 다른 DB. 스테이징 키가 새도 운영은 안전 |
| 교체 가능 | 키가 샜을 때 코드 변경 없이 새 키로 바꿀 수 있는 구조 |
| 출력 금지 | 로그, 에러 메시지, 헬스체크 응답에 비밀값을 찍지 않음 |
3.3 비밀값 등록은 내가 직접
README 9.2의 "내가 직접 (위임 불가)" 첫 줄에 있는 일입니다. AI에게는 필요한 환경변수의 이름 목록 만 받고, 실제 값은 내가 플랫폼 설정 화면에 직접 붙여 넣습니다. 키를 AI와의 대화에 붙여 넣으면 대화 기록에 남습니다. 대화 기록도 0절 축 2의 왼쪽(영구히 남는 곳)입니다.
4. ⭐ 배포 검증 — 명령 성공 ≠ 서비스 정상
4.1 정의
헬스체크 (health check) — [상태 확인 주소]인데, [ 서버가 스스로 "살아 있고 DB에 연결됐다"를 알려 주는 전용 응답 ]이라는 점에서 실제 기능을 호출하는 API와 구별된다.
스모크 테스트 (smoke test) — [배포 후 검증]인데, [ 핵심 기능 몇 개만 빠르게 호출해 "켜졌고 기본 동작은 한다"를 확인한다 ]는 점에서 모든 규칙을 확인하는 전체 테스트(17차시)와 구별된다. 이름은 "전원을 넣었을 때 연기가 나는지 본다"는 데서 왔습니다.
4.2 배포가 끝났다고 말하려면
| 확인 | 방법 | 기대 |
|---|---|---|
| 상태 확인 | curl https://api.classon.example/health | {"status":"ok","db":"connected"} |
| 스모크 테스트 | 핵심 API 몇 개 호출 | 클래스 목록 200, 인증 없는 예약 401 |
| 설정 확인 | 테스트 키로 동작하는지 (스테이징) | 실 결제 발생 안 함 |
| 로그 확인 | 플랫폼 로그 화면 | 에러 없음, 비밀값 출력 없음 |
| HTTPS | 브라우저 주소창 | 자물쇠 표시, 인증서 유효 |
🔍 읽는 포인트 : curl 줄은 주소(/health)와 기대 응답("ok", "connected")만 보면 됩니다. 앞에서 배운 상태 코드 (4차시)대로 200은 성공, 401은 "로그인 필요"입니다.
⭐ 이 표의 대부분은 코드 없이 할 수 있습니다. /health 주소를 브라우저로 열기, 자물쇠 확인, 클래스 목록 보기. "배포 성공"이라는 에이전트의 말(주장) 대신 이 다섯 줄(증거)로 끝을 판정합니다.
스모크 테스트를 스크립트로 만들어 두면 배포마다 같은 확인을 반복할 수 있습니다.
앞으로 다시 만납니다 — 22차시에서 이 스모크 스크립트를 자동 배포 흐름의 한 단계 로 넣고, 그 뒤에 E2E 테스트를 붙입니다.
5. 롤백 준비
5.1 정의와 경계
롤백 (rollback) — [되돌리기]인데, [ 배포된 서비스를 이전 버전의 실행본으로 바꿔 놓는다 ]는 점에서 코드 이력에 취소 커밋을 덧붙이는 git revert(18차시)와 구별된다.
git revert (18차시) | 롤백 (이 차시) | |
|---|---|---|
| 무엇을 되돌리나 | 저장소의 코드 | 실행 중인 서비스 |
| 얼마나 빠른가 | 커밋 → CI → 배포를 다시 거침 (분 단위 이상) | 플랫폼 버튼 하나 (보통 빠름) |
| 언제 | 원인을 알고 코드를 바로잡을 때 | ⭐ 장애 중, 피해부터 멈출 때 (23차시) |
롤백 방법은 배포 전에 알아 둡니다. 대부분의 PaaS에는 이전 배포로 되돌리는 기능이 있습니다(위치와 이름은 플랫폼마다 다르니 공식 문서 확인).
5.2 ⚠️ 반례 — 롤백으로 돌아오지 않는 것
0절 축 4의 오른쪽입니다. DB 마이그레이션은 코드처럼 쉽게 되돌아가지 않습니다. 코드를 이전 버전으로 돌려도 DB의 구조 변경과, 그 사이 들어온 데이터는 그대로입니다. 열을 지우는 마이그레이션이었다면 지워진 데이터는 돌아오지 않습니다(앞에서 배운 파괴적 마이그레이션, 12차시).
그래서 파괴적 마이그레이션은 코드 배포와 분리해서 , 별도 단계로 신중하게 합니다. 순서의 원칙은 "먼저 더하고, 나중에 지운다"입니다. 새 열을 추가하는 배포와 옛 열을 지우는 배포를 나누면, 첫 배포는 롤백해도 데이터가 다치지 않습니다.
5.3 대시보드의 세 자리를 미리 찾아 두기
장애가 나면(23차시) 코드를 고칠 시간이 없습니다. 배포 플랫폼 화면에서 아래 세 곳이 비상 장비 입니다.
| 자리 | 쓰는 때 |
|---|---|
| 로그 화면 | 무슨 일이 났는지 볼 때 |
| 환경변수(비밀값) 설정 화면 | 키를 교체할 때 |
| 이전 배포로 되돌리기(롤백) 버튼 | 피해부터 멈출 때 |
⚠️ 스테이징에서 롤백 버튼을 한 번 실제로 눌러 보세요. 처음 누르는 날이 장애 날이면 안 됩니다.
💡 비유는 마지막에 — 배포는 이삿짐 옮기기 입니다. 이미지는 짐을 싼 상자, 비밀값은 상자에 넣지 않고 새집 문 앞에서 직접 건네는 열쇠 , 스모크 테스트는 이사 직후 전기 · 수도 · 가스가 들어오는지 확인하는 것, 롤백은 원래 집 열쇠를 아직 반납하지 않은 상태 입니다.
6. 클래스온에 적용하면
| 항목 | 클래스온 |
|---|---|
| 실행 플랫폼 | 앞에서 기록한 아키텍처 결정 (8차시)에 따른 PaaS 하나 |
| 환경 | 스테이징 / 운영 분리. 키 · DB 모두 다름 |
| 비밀값 | DB 주소, PG 비밀 키(스테이징은 테스트 키 ), 로그인 서명 키 — 전부 플랫폼 설정 화면에 내가 등록 |
| 배포 검증 | /health + scripts/smoke.sh (목록 200, 인증 없는 예약 401) |
| 롤백 | 플랫폼 롤백 버튼 위치 확인 + 스테이징에서 1회 실제로 눌러 봄 |
7. 실습 — 맡기고 검수하기
지시
결정 기록(ADR-0003)에 따라 apps/api를 스테이징 환경에 배포할 설정을 만들어줘.
- 필요한 환경변수 목록을 표로 정리하되, 값은 넣지 마 (내가 플랫폼에 직접 등록할 것).
표 형식: | 이름 | 무엇에 쓰나 | 비밀값인가(예/아니오) | 스테이징과 운영이 달라야 하나 |
- Dockerfile에 비밀값이 들어가지 않았음을 확인하고, 확인한 방법을 적어줘.
- 배포 후 실행할 스모크 테스트를 scripts/smoke.sh로 만들어줘. 각 확인마다 [확인 | 기대 | 실제 | 통과/실패] 한 줄씩 출력하게.
- 실제 배포 명령은 실행하지 마. 내가 실행할 명령만 알려줘.
배포는 내가 한 뒤에 알려 줄 테니, 그때 스모크 테스트를 돌리고 출력 원문을 그대로 붙여.
🔍 읽는 포인트 : "값은 넣지 마", "실제 배포 명령은 실행하지 마"가 되돌리기 어려운 일은 사람이 라는 원칙(20차시 3절)을 지시로 옮긴 것입니다.
받을 증거
- 환경변수 이름 목록 표 (값 없음)
- Dockerfile에 비밀값이 없다는 확인 방법과 결과
- 배포 후
smoke.sh실행 출력 원문 (한 줄씩 통과 / 실패) - 내가 실행할 배포 명령과, 그 플랫폼의 롤백 방법 (화면 위치)
내가 직접 확인할 것
| 볼 것 | 이걸로 아는 것 / 왜 내가 보는가 |
|---|---|
| 환경변수 표의 값 칸이 비어 있는가 | AI가 키를 다루지 않았다. 값은 내가 직접 플랫폼 화면에 입력 |
브라우저로 https://.../health 열기 | "ok", "connected"가 보이면 서버와 DB가 살아 있다 |
| 주소창 자물쇠 | HTTPS · 인증서 정상 |
| 브라우저로 클래스 목록 주소 열기 | 실제 데이터가 나온다. 스모크 테스트의 말과 내 눈이 일치하는가 |
| 플랫폼 로그 화면 | 에러가 없고, 키 같은 문자열이 찍혀 있지 않은가 |
| ⭐ 행동 시험: 스테이징에서 롤백 버튼을 눌러 보고, 다시 최신으로 | 비상 장비가 실제로 작동한다 . 버튼 위치를 손이 기억하게 |
부록 A. 스스로 확인하기
| # | 질문 | 답이 있는 곳 |
|---|---|---|
| 1 | 배포와 스테이징을 유와 종차로 정의하면? | 1.1 |
| 2 | 로컬과 배포 환경에서 달라지는 네 가지는? | 1.2 |
| 3 | main에 병합한 것이 배포가 아닌 이유는? | 1.3 |
| 4 | 코드가 인터넷에서 응답하기까지의 단계는? 컨테이너 이미지는 무엇인가? | 2.1 |
| 5 | PaaS가 입문에 적합한 이유는? | 2.2 |
| 6 | 이미지 안에 비밀값을 넣으면 왜 위험한가? | 3.1 |
| 7 | 비밀값 관리의 네 원칙은? 스테이징과 운영의 키를 분리하는 이유는? | 3.2 |
| 8 | 비밀값을 AI와의 대화에 붙여 넣으면 안 되는 이유는? | 3.3 |
| 9 | "배포 성공"을 판정하는 확인 다섯 가지는? 헬스체크와 스모크 테스트의 차이는? | 4.1, 4.2 |
| 10 | 롤백과 git revert는 무엇이 다른가? 장애 중에는 어느 쪽인가? | 5.1 |
| 11 | DB 마이그레이션이 롤백으로 돌아오지 않는 이유와 대처는? | 5.2 |
부록 B. 자주 하는 실수
| 실수 | 바로잡기 |
|---|---|
| 비밀값을 Dockerfile이나 이미지에 넣는다 | ❌ 이미지를 받은 누구나 꺼내 봅니다. 실행 시 주입 (3.1) |
| 스테이징과 운영에 같은 DB, 같은 키를 쓴다 | ❌ 환경별 분리 (3.2) |
| 배포 명령 성공 메시지만 보고 끝낸다 | ⚠️ 주장입니다. 헬스체크 · 스모크 테스트로 (4.2) |
| 롤백 방법을 사고가 난 뒤에 찾아본다 | ⭕ 배포 전에 찾고, 스테이징에서 한 번 눌러 본다 (5.3) |
| 에이전트가 플랫폼 비밀값을 설정하도록 실제 키를 대화에 붙여 넣는다 | ❌ 이름만 받고 값은 내가 직접 등록 (3.3) |
| 열을 지우는 마이그레이션과 코드 변경을 한 번에 배포한다 | ⚠️ 롤백해도 데이터는 안 돌아옵니다. 먼저 더하고 나중에 지운다 (5.2) |
| 컨테이너 안에 파일을 저장해 두고 재시작 후 사라져서 당황한다 | ⚠️ 배포 환경의 파일 시스템은 사라질 수 있습니다 (1.2) |
부록 C. NotebookLM 복습 프롬프트
이 21차시 노트만 근거로 5문제를 내줘. 비전공자 기준으로.
"구워 넣기와 실행 시 주입의 차이", "배포 명령 성공과 서비스 정상의 차이", "롤백과 git revert의 차이"는 반드시 포함해줘.
답은 내가 답한 다음에 채점하고, 틀린 이유를 노트의 절 번호를 근거로 설명해줘.
LangTailor