바이브코딩 서비스를 Docker 컨테이너로 실전서비스 론칭하기 · 1부 — 바이브코딩 셋업부터 컨테이너 실행까지

4장. 로컬에서 서비스 만들기 (React + Express + PostgreSQL)

드디어 서비스를 만듭니다. 3장에서 "무엇을 만들지"를 기획으로 정리했으니, 이번 장에서는 그 기획을 실제로 동작하는 서비스로 바꿉니다. 다시 강조하지만, 여러분은 코드를 한 줄도 직접 타이핑하지 않습니다. 3장에서 정리한 기획을 Claude Code에게 넘기고, "요청(프롬프트) → 승인 → 확인"을 반복하며 완성해 나갑니다. 이 장의 핵심은 "어떤 코드가 만들어지는가"가 아니라 "어떻게 요청하고, 무엇을 확인하는가" 입니다.

한 조각을 만들 때마다 눈으로 확인하고 다음으로 넘어갑니다. 그래야 문제가 생겨도 어디서 틀어졌는지 바로 찾을 수 있습니다. 순서대로 따라오세요.

[지금 여기]

우리는 22단계를 거쳐 "라이브 투표 서비스"를 직접 만들고, 컨테이너에 담아, AWS 클라우드에 배포합니다. 아래가 그 전체 여정 지도입니다. 지금은 4단계, 서비스를 처음으로 내 컴퓨터에서 동작시키는 자리에 있습니다.

  1. 1장개발 환경 준비 (터미널 / Node.js / Git / GitHub / VS Code / Claude Code)
  2. 2장Claude Code 사용법 익히기
  3. 3장무엇을 만들지 기획 (라이브 투표 서비스)
  4. 4장로컬에서 서비스 만들기 (React + Express + PostgreSQL)
  5. 5장Docker 개념
  6. 6장Dockerfile 작성
  7. 7장컨테이너 빌드·실행
  8. 8장AWS 시작 (계정 / IAM / 리전 / 비용)
  9. 9장이미지 태깅
  10. 10장ECR에 이미지 올리기
  11. 11장VPC 네트워크 구성
  12. 12장RDS 데이터베이스 생성
  13. 13장SSM 터널로 RDS 초기화
  14. 14장ECS Fargate + ALB로 배포 (기본 완성)
  15. 15장CI/CD (GitHub Actions)
  16. 16장IaC (Terraform)
  17. 17장배포 자동화 연결
  18. 18장현업 운영 구조 이해
  19. 19장무중단 배포
  20. 20장신규 버전 배포 & 롤백
  21. 21장(심화) 프론트를 Vercel로 분리 배포
  22. 22장마무리 (회고 + 리소스 삭제)

이번 장에서 완성되는 것

한 문장으로: 투표를 만들고, 표를 던지고, 결과를 막대그래프로 보는 웹 서비스가 내 컴퓨터에서 돌아가고, 새로고침해도 결과가 그대로 남습니다.

이렇게 되면 성공입니다: 브라우저에서 http://localhost:5173에 접속해 설문을 만들고 투표한 뒤, 페이지를 새로고침해도 득표수가 사라지지 않고 그대로 보입니다. 그리고 그 코드가 GitHub의 내 비공개 저장소에 올라가 있습니다.

사전 조건

이 장은 1~3장의 결과물 위에서 시작합니다. 아래가 갖춰져 있어야 합니다.

pwd            # 경로 끝이 /vote-app 이어야 합니다
claude         # Claude Code 실행 (AI 입력창이 뜹니다)
주의

이 장에는 Docker Desktop이 하나 더 필요합니다 뒤(4.6)에서 데이터베이스를 Docker로 띄웁니다. 그때 Docker Desktop이 설치돼 있고 실행 중이어야 합니다. 아직 없다면 지금 미리 https://www.docker.com/products/docker-desktop 에서 내 운영체제용 설치 파일을 받아 설치하고, 설치 후 Docker Desktop 앱을 한 번 실행해 두세요. (Docker가 정확히 무엇인지는 5장에서 제대로 배웁니다. 여기서는 "DB를 간편하게 띄우는 도구"로만 씁니다.) 설치가 부담되면 4.5까지 먼저 진행하고, 5장의 Docker 설치 안내를 본 뒤 4.6으로 돌아와도 됩니다.

4.1 우리가 만들 서비스의 3층 구조

본격적으로 만들기 전에, 우리가 만들 서비스가 어떤 조각들로 이루어지는지 알아 둡시다. 대부분의 웹 서비스는 세 개의 층으로 나뉩니다.

용어

프론트엔드(Frontend) 사용자가 눈으로 보고 클릭하는 화면 부분입니다. 브라우저에서 돌아갑니다. 우리 서비스에서는 투표 화면, 결과 막대그래프가 여기에 해당합니다. (React로 만듭니다.)

용어

백엔드 / API 서버(Backend) 화면 뒤에서 실제 일을 처리하는 부분입니다. "투표 한 표 더하기", "설문 정보 가져오기" 같은 요청을 받아 처리하고, 데이터베이스를 다룹니다. 사용자 눈에는 보이지 않습니다. (Node.js + Express로 만듭니다.)

용어

데이터베이스(Database, DB) 정보를 저장해 두는 창고입니다. 설문 내용, 선택지, 득표수가 여기에 쌓입니다. 서버가 이 창고에 정보를 넣고 꺼냅니다. (PostgreSQL을 씁니다.)

세 층은 이렇게 협력합니다. 사용자가 화면(프론트엔드)에서 버튼을 누르면, 그 요청이 API 서버(백엔드)로 가고, 서버는 데이터베이스에서 값을 꺼내거나 바꾼 뒤 결과를 화면으로 돌려줍니다.

프론트엔드React · 화면백엔드 / API 서버Express · 요청 처리데이터베이스PostgreSQL · 저장예) 사용자가 "파스타" 클릭 → 프론트가 API에 "3번 투표" 요청→ API가 DB의 votes를 +1 → 응답 → 프론트가 막대그래프 갱신

실제로 어디에 쓰이나. 이 3층 구조는 우리 투표 서비스만의 특별한 방식이 아니라, 여러분이 매일 쓰는 서비스 대부분이 이 구조입니다.

공통점이 보이죠. 보여 주는 층 / 처리하는 층 / 저장하는 층을 나누면, 각 층을 따로 만들고 따로 고칠 수 있어 편합니다. 우리도 이 순서대로 프론트 → API → DB를 하나씩 붙여 갑니다. 이 그림을 머릿속에 넣어 두면, 앞으로 무엇을 만드는지 길을 잃지 않습니다.

4.2 프로젝트 뼈대 만들기

이제 3장에서 준비한 기획을 Claude Code에 넣습니다. 곧바로 코드를 만들게 하지 말고, 계획을 먼저 받아 보는 게 좋습니다. 2장에서 배운 대로 "아직 코드는 만들지 말고 계획부터"를 잊지 마세요.

프롬프트

(AI 입력창에 입력, vote-app에서 실행 중인 claude)

3장에서 정리한 라이브 투표 서비스를 만들려고 해.
프론트엔드는 React, API 서버는 Express, DB는 PostgreSQL을 쓸 거야.
아직 코드는 만들지 말고, 어떤 순서로 만들지 계획부터 알려 줘.

Claude Code가 만들 순서를 계획으로 제시하면, 방향이 맞는지 읽어 봅니다. 프론트 → API → DB 순서로 하나씩 붙이는 계획이면 좋습니다. 확인했으면 뼈대부터 만들라고 승인합니다.

프롬프트
좋아, 이 계획대로 먼저 프로젝트 뼈대만 만들어 줘.
vote-app 안에 frontend 폴더(React)와 backend 폴더(Express)로 나눠 줘.
용어

프로젝트 뼈대(Boilerplate / Scaffold) 서비스의 기본 틀입니다. 아직 기능은 없지만, 프론트엔드 폴더와 백엔드 폴더, 기본 설정 파일 등 "앞으로 살을 붙일 골격"이 갖춰진 상태입니다.

Claude Code는 뼈대를 만들 때 여러분 대신 명령을 실행합니다. 예를 들어 프론트는 npm create vite@latest frontend -- --template react 같은 명령으로 React 프로젝트를 만들고, 백엔드는 npm init으로 Express 프로젝트를 준비합니다. 이런 명령을 실행하기 전에 Claude Code가 "실행해도 될까요?"라고 물으면, 내용을 보고 승인하면 됩니다. (직접 외워서 칠 필요는 없습니다.)

확인

뼈대가 만들어졌으면 VS Code 왼쪽의 파일 목록에 frontendbackend 폴더가 생깁니다. 대략 이런 모양입니다(세부 파일 이름은 다를 수 있습니다).

vote-app/
├── frontend/     프론트엔드(React) 코드가 사는 곳
├── backend/      백엔드(Express) 코드가 사는 곳
└── ...           기타 설정 파일

폴더 구조가 예시와 조금 달라도 괜찮습니다. 중요한 건 "프론트와 백엔드가 나뉘어 있구나" 정도입니다. 궁금하면 Claude Code에게 "지금 폴더 구조를 설명해 줘"라고 물어보세요.

4.3 프론트엔드 만들기 — 투표 화면

이제 사용자가 볼 화면부터 만들어 달라고 합니다. 화면은 React라는 도구로 만듭니다.

용어

React / Vite - React: 화면(프론트엔드)을 만드는 데 가장 널리 쓰는 도구입니다. 화면을 "버튼", "목록", "그래프" 같은 조각(컴포넌트)으로 나눠서 만들고, 데이터가 바뀌면 화면을 알아서 다시 그려 줍니다. - Vite: React로 만든 화면을 빠르게 실행하고 미리 볼 수 있게 해 주는 도구입니다. 개발 중 화면을 브라우저에 띄워 확인할 때 씁니다. 둘 다 Claude Code가 알아서 설정하므로, 이름과 역할만 알아 두면 됩니다.

실제로 어디에 쓰이나. React는 취미 프로젝트용 장난감이 아니라, 큰 회사들이 실제 서비스 화면을 만드는 데 씁니다.

즉, 우리가 배우는 도구가 곧 현업에서 쓰는 도구입니다. 이제 투표 화면을 만들어 달라고 요청합시다.

프롬프트
frontend 쪽에 투표 화면을 만들어 줘.
- 설문의 질문과 선택지들이 보이고
- 선택지를 누르면 투표가 되고
- 각 선택지의 득표수가 막대그래프로 표시되면 좋겠어
아직 서버가 없으니, 우선 가짜 데이터로 화면만 확인할 수 있게 해 줘.
그리고 나중에 API를 붙일 때를 위해, API 호출은 절대 주소가 아니라
상대 경로(/api)로 부르게 하고, vite.config에 개발 프록시를 설정해서
/api 요청을 localhost:3000(API 서버)으로 넘기게 해 줘. (CORS 방지)

"우선 가짜 데이터로 화면만"이라고 요청한 데 주목하세요. 서버와 DB가 아직 없어도 화면을 먼저 눈으로 확인하기 위한 요령입니다. 이렇게 조각을 하나씩 확인하며 나아가면 문제가 생겨도 원인을 찾기 쉽습니다. 프롬프트 뒤쪽의 "상대 경로(/api) + 개발 프록시"가 왜 중요한지는 4.5에서 따로 설명합니다. 지금은 그냥 그렇게 시켜 두기만 하면 됩니다.

[맛보기] 만든 화면을 브라우저에 띄워 보기

만들어졌으면 실제로 화면을 띄워, 처음으로 내 손으로 결과를 확인해 봅니다.

프롬프트
프론트엔드 개발 서버를 실행해서 브라우저로 확인할 수 있게 해 줘.
접속 주소도 알려 줘.

Claude Code가 개발 서버를 실행하고 http://localhost:5173 같은 주소를 알려 줍니다. 그 주소를 브라우저 주소창에 입력해, 투표 화면이 뜨는지 눈으로 확인하세요. 아직 가짜 데이터지만 질문·선택지·막대그래프 모양이 잡혔으면 성공입니다.

참고

http://localhost:51735173은 Vite 개발 서버가 쓰는 "포트 번호"입니다. 한 컴퓨터 안에서 여러 프로그램이 각자 다른 번호(문)로 통신하는데, Vite는 보통 5173번을 씁니다. 뒤에서 만들 API 서버는 3000번을 씁니다. 번호가 다르면 서로 다른 프로그램이라고 생각하면 됩니다.

주의

화면이 이상하거나 안 뜨면, 2장에서 배운 대로 터미널에 나온 오류 메시지를 그대로 복사해 Claude Code에게 붙여넣고 고쳐 달라고 하세요. 이 "오류 붙여넣고 고치기" 과정 자체가 정상적인 개발 흐름입니다.

설문 만들기 화면도 추가하기

투표 화면이 잡혔으니, 새 설문을 직접 만드는 화면도 있어야 3장 완료 기준의 "설문을 만들고"가 채워집니다. 이어서 요청합니다.

프롬프트
홈 화면에 '설문 만들기' 화면을 만들어 줘.
- 질문 입력칸 하나
- 선택지 입력칸 여러 개 (기본 2개, '선택지 추가' 버튼으로 늘리고
  지우기도 가능)
- '설문 만들기' 버튼을 누르면 설문이 만들어지고, 그 설문의 투표
  화면으로 이동
- 빈 질문이거나 선택지가 2개 미만이면 안내 문구를 보여 줘
투표 화면과 어울리는 디자인으로 해 줘.

완성되면 홈 화면이 이렇게 보입니다. (선택지는 아직 서버가 없으니, 이 화면의 "만들기"가 실제로 저장되는 것은 4.4~4.6에서 API와 DB를 붙인 뒤부터입니다.)

설문 만들기 화면 — 질문과 선택지를 입력하고 만들기

4.4 API 서버 만들기 — 설문·투표·결과

화면이 잡혔으니, 이번엔 뒤에서 일할 API 서버를 만듭니다. API 서버는 Express라는 도구로 만듭니다.

용어

Express Node.js에서 API 서버를 만들 때 가장 많이 쓰는 도구입니다. "이 주소로 요청이 오면 이 일을 해라"라는 규칙(엔드포인트)을 간단하게 정의할 수 있게 해 줍니다.

용어

엔드포인트(Endpoint) 서버가 열어 두는 "요청 창구"입니다. POST /api/polls처럼 "주소 + 방식"의 짝으로, 각 창구가 하나의 일(설문 만들기, 투표하기 등)을 맡습니다.

실제로 어디에 쓰이나. 우리가 화면에서 무언가를 누를 때, 뒤에서는 거의 항상 이런 API 서버가 요청을 받아 처리합니다.

우리 투표 서비스에서는 3장에서 정리한 세 개의 창구(엔드포인트)를 그대로 요청합니다.

프롬프트
backend 쪽에 Express로 API 서버를 만들어 줘. 엔드포인트는 세 개야.
- POST /api/polls        : 질문과 선택지를 받아 설문을 만든다
- GET  /api/polls/:id    : 설문의 질문·선택지·득표수를 돌려준다
- POST /api/polls/:id/vote : 고른 선택지의 득표수를 1 늘린다
DB는 잠시 뒤에 붙일 거니까, 지금은 서버 메모리에 임시로 저장하는
방식으로 먼저 동작하게 해 줘. 서버는 3000번 포트로 열어 줘.

여기서도 "DB는 나중에, 지금은 임시 저장으로 먼저"라는 단계 나누기를 썼습니다. 서버가 혼자서도 동작하는지 먼저 확인한 뒤 DB를 붙이면, 문제의 원인이 서버인지 DB인지 구분하기 쉽습니다.

[맛보기] API가 실제로 응답하는지 확인하기

프롬프트
API 서버를 실행하고, 세 개의 엔드포인트가 잘 동작하는지
간단히 테스트해서 결과를 보여 줘.

Claude Code가 서버를 실행하고, 스스로 요청을 보내 응답을 확인한 결과를 알려 줍니다. "설문 생성 성공", "투표 후 득표수 증가 확인" 같은 결과가 나오면 서버가 제대로 도는 것입니다. 화면 없이 서버 혼자서도 일을 한다는 걸 눈으로 본 셈입니다.

4.5 왜 상대 경로 /api로 부를까 — CORS와 개발 프록시

이제 화면(5173번)과 API 서버(3000번)가 둘 다 준비됐습니다. 그런데 이 둘을 연결하려 할 때 초보자가 거의 반드시 만나는 문제가 하나 있습니다. 미리 피해 두었으니, 왜 그렇게 했는지 이해하고 넘어갑시다.

용어

CORS (교차 출처 요청 차단) 브라우저의 보안 규칙입니다. 화면이 실행되는 주소(localhost:5173)와, 화면이 데이터를 요청하는 주소(localhost:3000)가 서로 다르면, 브라우저는 "출처(origin)가 다르다"며 그 요청을 기본적으로 막습니다. 이 막힘을 CORS 문제라고 부릅니다.

용어

개발 프록시(Dev Proxy) "요청을 대신 전달해 주는 중개인"입니다. 화면은 늘 자기 자신(5173번)에게만 요청을 보내고, Vite가 그중 /api로 시작하는 요청만 몰래 3000번(API 서버)으로 넘겨 줍니다. 화면 입장에서는 계속 같은 주소랑만 대화하므로, 브라우저가 "출처가 다르다"고 막을 일이 없습니다.

그래서 4.3의 프롬프트에서 두 가지를 미리 시켜 둔 것입니다.

  1. 화면이 API를 부를 때 절대 주소(http://localhost:3000/...)가 아니라 상대 경로(/api/...)로 부르게 했습니다.
  2. vite.config개발 프록시를 설정해, /api 요청을 3000번으로 넘기게 했습니다. (Vite가 만들어 준 설정은 대략 이런 모습입니다.)
// frontend/vite.config.js — Claude Code가 만든 설정 예시 (직접 칠 필요 없음)
server: {
  proxy: {
    '/api': {
      target: 'http://localhost:3000',  // /api 요청을 API 서버로 넘김
      changeOrigin: true,
    },
  },
}

실제로 어디에 쓰이나. "화면과 API가 같은 주소인 것처럼 보이게" 하는 이 방식은 개발 현장에서 표준처럼 쓰입니다.

즉 이 "상대 경로 /api" 습관 하나로 개발할 때도, 나중에 AWS에 배포할 때도 CORS 문제를 아예 겪지 않게 됩니다. 그래서 처음부터 이렇게 시켜 둔 것입니다.

4.6 데이터베이스 붙이기 — 로컬에서 PostgreSQL

지금까지는 서버 메모리에 임시로 저장했습니다. 문제는, 서버를 끄면 그 데이터가 전부 사라진다는 점입니다. 3장 완료 기준의 마지막 항목, "새로고침해도 결과가 유지된다"를 만족하려면 데이터를 진짜 창고(DB)에 저장해야 합니다.

용어

PostgreSQL 널리 쓰이는 무료 데이터베이스입니다. 표(테이블) 형태로 데이터를 저장하고, 정확하고 안정적이어서 실무에서 많이 씁니다. 뒤에서 AWS에 배포할 때 쓰는 클라우드 DB(RDS)도 이 PostgreSQL을 그대로 씁니다.

우리가 쓸 DB는 PostgreSQL입니다. 그런데 내 컴퓨터에 PostgreSQL을 직접 설치하는 대신, Docker로 띄웁니다.

용어

Docker (지금은 맛보기) 프로그램을 "상자"에 담아 어디서든 똑같이 실행하게 해 주는 도구입니다. PostgreSQL을 내 컴퓨터에 복잡하게 설치하지 않고도, Docker로 명령 한 번에 깔끔하게 띄웠다가 지울 수 있습니다. Docker가 정확히 무엇이고 왜 쓰는지는 바로 다음 5장에서 제대로 배웁니다. 지금은 "DB를 간편하게 띄우는 도구"라는 정도로만 알고, 실행은 Claude Code에게 맡깁니다.

왜 설치 대신 Docker로 띄우나. 데이터베이스를 컴퓨터에 직접 설치하면 버전이 꼬이거나, 나중에 지우기가 번거롭습니다. Docker로 띄우면 명령 한 줄로 깨끗하게 시작하고, 필요 없어지면 상자째 지우면 그만이라 내 컴퓨터가 지저분해지지 않습니다. 그래서 로컬 개발용 DB는 Docker로 띄우는 경우가 많습니다.

주의

Docker Desktop이 실행 중이어야 합니다 사전 조건에서 설치한 Docker Desktop이 지금 실행 중인지 확인하세요. (macOS는 위쪽 메뉴막대의 고래 아이콘, Windows는 작업 표시줄의 고래 아이콘이 떠 있으면 실행 중입니다.) 실행돼 있지 않으면 Docker로 DB를 띄우는 단계에서 오류가 납니다. Docker Desktop 앱을 먼저 실행해 두세요.

DB 붙이기 요청

프롬프트
이제 데이터를 PostgreSQL에 저장하도록 바꿔 줘.
- 로컬 개발용 PostgreSQL은 Docker로 띄워 줘
- polls(id, question, created_at), options(id, poll_id, label, votes)
  구조로 테이블을 만들어 줘
- 서버가 임시 저장 대신 이 DB에 저장하고 읽도록 연결해 줘

Claude Code가 Docker로 PostgreSQL을 실행하고(예: docker run 명령으로 postgres 상자를 5432번 포트에 띄웁니다), 테이블을 만들고, 서버가 DB를 쓰도록 코드를 고쳐 줍니다. 중간에 여러 명령을 실행하며 승인을 요청할 텐데, 내용을 보며 승인하면 됩니다.

용어

테이블(Table) DB 안에서 정보를 담는 "표"입니다. 3장에서 그린 polls, options 데이터 모델이 실제로는 이 테이블 두 개가 됩니다. polls에는 설문 하나하나가, options에는 그 설문의 선택지와 득표수가 한 줄씩 쌓입니다.

참고

DB에 연결하려면 서버 코드가 "DB 주소, 사용자 이름, 비밀번호"를 알아야 합니다. 지금은 Claude Code가 우선 동작하게 채워 넣지만, 이렇게 코드에 들어간 접속 정보(특히 비밀번호)는 4.8에서 .env 파일로 옮겨 분리합니다. 지금은 일단 동작부터 확인하고 넘어갑니다.

4.7 전체 흐름 로컬에서 확인하기

이제 세 층(프론트 → API → DB)이 모두 준비됐습니다. 실제로 처음부터 끝까지 이어지는지 확인할 차례입니다.

프롬프트
프론트엔드, API 서버, 그리고 Docker의 DB를 모두 실행해서
전체가 연결된 상태로 확인할 수 있게 해 줘. 접속 주소를 알려 줘.
참고

여러 개가 동시에 돕니다 이 단계에서는 세 가지(프론트 개발 서버, API 서버, DB)가 동시에 켜져 있어야 합니다. Claude Code는 이를 위해 터미널을 여러 개 열거나 프로그램을 백그라운드로 돌릴 수 있습니다. 승인을 요청하면 그대로 승인하세요. 이때 claude가 실행 중인 터미널은 닫지 마세요. 무언가 멈추면 Claude Code에게 "지금 프론트, API, DB가 다 켜져 있는지 확인해 줘"라고 물으면 됩니다.

브라우저에서 알려 준 주소(보통 http://localhost:5173)에 접속해, 3장의 완료 기준을 하나씩 직접 체크해 보세요.

마지막 항목이 이제 통과되어야 합니다. 새로고침해도 데이터가 유지된다면, 값이 화면이나 서버 메모리가 아니라 DB에 제대로 저장되고 있다는 확실한 증거입니다. 축하합니다. 프론트 + API + DB로 이루어진 진짜 웹 서비스가 내 컴퓨터에서 돌고 있습니다.

선택지를 누르면 아래처럼 득표수가 막대그래프와 퍼센트로 나타납니다.

투표 화면 — 선택지를 누르면 득표수가 막대그래프와 퍼센트로 보인다

주의

새로고침했더니 결과가 사라진다면, 아직 DB가 아니라 메모리에 저장되고 있을 수 있습니다. Claude Code에게 "새로고침하면 투표 결과가 사라져. DB에 저장되고 있는 게 맞는지 확인하고 고쳐 줘"라고 요청하세요.

4.8 환경변수 분리 — 접속 정보를 코드에 넣지 않기

서비스가 동작하니, 넘어가기 전에 한 가지 중요한 습관을 짚습니다. DB에 접속하려면 주소, 사용자 이름, 비밀번호 같은 정보가 필요합니다. 이런 민감한 정보를 코드 안에 그대로 적어 두면 안 됩니다.

용어

환경변수(Environment Variable) 프로그램 바깥에서 값을 주입하는 설정값입니다. DB 비밀번호처럼 환경마다 달라지거나 숨겨야 하는 값을, 코드에 직접 쓰지 않고 바깥에서 전달합니다.

용어

시크릿(Secret) 비밀번호, 접속 키처럼 남에게 노출되면 안 되는 민감한 값들을 가리킵니다. 환경변수로 관리하는 대표적인 대상입니다.

왜 코드에 직접 쓰면 안 되나. 두 가지 이유가 있고, 둘 다 실무에서 실제로 사고로 이어지는 것들입니다.

  1. 보안: 코드를 GitHub에 올리면, 코드에 박아 둔 비밀번호까지 인터넷에 공개됩니다. 실제로 이렇게 유출된 접속 정보로 남의 DB가 털리는 사고가 흔합니다.
  2. 유연성: 내 컴퓨터의 DB와, 나중에 AWS의 DB는 접속 정보가 다릅니다. 코드에 박아 두면 환경이 바뀔 때마다 코드를 고쳐야 합니다. 환경변수로 빼 두면 코드는 그대로 두고 값만 바꾸면 됩니다.

그래서 이런 값들은 보통 .env라는 별도 파일에 모아 둡니다.

용어

.env 파일 환경변수들을 모아 적어 두는 파일입니다. DB_PASSWORD=... 같은 식으로 값을 담아 두면, 프로그램이 실행될 때 이 값을 읽어 씁니다. 이 파일은 GitHub에 올리지 않도록 따로 제외합니다. [프롬프트]

DB 접속 정보 같은 민감한 값이 코드에 직접 들어가 있으면
.env 파일로 분리해 줘. 환경변수 이름은 아래 다섯 개로 맞춰 줘.
  DB_HOST, DB_PORT, DB_NAME, DB_USER, DB_PASSWORD
그리고 .env가 실수로 GitHub에 올라가지 않도록
.gitignore에도 추가해 줘. 분리한 뒤에도 서비스가 그대로 동작하는지
확인해 줘.
주의

환경변수 이름을 왜 콕 집어 주나요 DB_HOST 같은 이름을 지정하지 않으면 AI가 DATABASE_URL 하나로 합치거나 POSTGRES_HOST처럼 다른 이름을 고를 수 있습니다. 그런데 이 다섯 개 이름은 7장(도커 컴포즈)과 2부(AWS 배포)에서 그대로 다시 씁니다. 지금 이름을 맞춰 두면, 나중에 배포할 때 서버 코드를 한 줄도 고치지 않아도 됩니다. 그래서 처음부터 못 박아 둡니다. [용어] .gitignore "GitHub에 올리지 않을 파일 목록"을 적어 두는 파일입니다. 여기에 .env를 넣어 두면, 비밀번호가 담긴 파일이 실수로 인터넷에 공개되는 걸 막습니다. [확인] 분리가 끝나면 VS Code 파일 목록에 .env 파일이 보이고, 그 안에 DB_PASSWORD=... 같은 값이 들어 있습니다. 그리고 .gitignore 파일 안에 .env라는 줄이 있어야 합니다. 이 두 가지를 눈으로 확인하세요.

4.9 Git으로 저장하고 GitHub에 올리기

마지막으로, 지금까지 만든 것을 안전하게 저장하고 GitHub에 올립니다. 2부와 3부의 자동 배포가 이 GitHub 저장소를 기반으로 이루어지므로, 여기서 꼭 올려 둬야 합니다. 1장에서 Git 설치와 GitHub 계정을 준비해 둔 걸 이제 씁니다.

용어

커밋(Commit) 지금까지의 변경 사항을 하나의 "저장 지점"으로 기록하는 것입니다. 게임의 세이브 포인트처럼, 나중에 이 시점으로 되돌아올 수 있습니다.

용어

푸시(Push) 내 컴퓨터에 기록한 커밋들을 GitHub(인터넷 저장소)로 올려 보내는 것입니다.

용어

리포지토리(Repository, 줄여서 repo) GitHub에서 하나의 프로젝트 코드가 통째로 저장되는 공간입니다. "vote-app 저장소"처럼 프로젝트마다 하나씩 만듭니다.

실제로 어디에 쓰이나. 이 커밋·푸시·저장소는 개발자라면 매일 쓰는 기본 도구입니다.

이 과정도 Claude Code에게 맡길 수 있습니다.

프롬프트
지금까지 만든 걸 git으로 커밋하고, GitHub에 새 저장소를 만들어
올려 줘. 저장소 이름은 vote-app, 프라이빗(비공개) 저장소로 해 줘.
참고

왜 프라이빗(비공개)으로 하나요? 퍼블릭(공개) 저장소는 전 세계 누구나 코드를 볼 수 있습니다. 우리 저장소에는 앞으로 배포 설정 등 우리 서비스의 속사정이 쌓이므로, 실습에서는 비공개로 두는 것이 안전합니다. (비공개여도 GitHub Actions 등 이 책의 모든 실습은 그대로 됩니다.) [주의] GitHub 연결(인증) 처음 올릴 때는 GitHub 로그인/인증 절차가 필요할 수 있습니다. Claude Code가 안내하는 대로 따라가면 되고, 막히면 오류 메시지를 그대로 붙여넣어 도움을 받으세요. gh라는 GitHub 공식 도구를 쓰면 편한데, 없으면 Claude Code가 설치 방법을 알려 줍니다. [확인] 올리고 나면 브라우저에서 github.com/내아이디/vote-app에 접속해, 코드가 실제로 올라왔는지 확인하세요. frontend, backend 폴더가 보여야 합니다. 이때 .env 파일은 목록에 없어야 정상입니다 (4.8에서 제외했으니까요). 만약 .env가 올라가 있다면, Claude Code에게 ".env가 저장소에 올라가 있어. .gitignore에서 제외하고 저장소에서도 지운 뒤 다시 올려 줘"라고 요청하세요.

[확인]

이번 장이 제대로 끝났는지 눈으로 확인합니다.

여기까지 보였다면, 내 컴퓨터에서 도는 진짜 웹 서비스가 완성된 것입니다.

막히면

이 장에서 자주 나는 오류와 대처법입니다.

[체크리스트]

아래가 모두 됐는지 확인해 보세요. 하나라도 안 됐다면 해당 절로 돌아가 다시 진행합니다.

이제 "내 컴퓨터에서 도는 서비스"가 생겼습니다. 하지만 이걸 다른 사람에게 보여 주려면 내 컴퓨터를 계속 켜 둘 수도 없고, "내 컴퓨터에선 되는데 남의 컴퓨터에선 안 되는" 문제도 있습니다. 이 문제를 푸는 것이 다음 여정, Docker와 클라우드 배포입니다.