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

3장. AI 서비스 기획 — 라이브 투표 서비스

앞 장에서 Claude Code에게 말로 지시해 결과를 얻는 법을 익혔습니다. 그리고 "좋은 프롬프트가 좋은 결과를 만든다"는 것도 보았습니다. 그렇다면 좋은 프롬프트는 어디서 나올까요? 바로 기획에서 나옵니다. 무엇을 만들지가 내 머릿속에서 분명해야, AI에게도 분명하게 전달할 수 있습니다.

이번 장에서는 이 책 내내 만들고, 컨테이너에 담고, AWS에 배포하고, 운영할 서비스인 라이브 투표 서비스를 기획합니다. 이 장은 앞뒤 장과 성격이 조금 다릅니다. 무언가를 설치하거나 명령어를 실행하지 않습니다. 대신 종이에 그리듯, "무엇을 만들지"를 한 장으로 정리합니다. 마지막에는 그 정리한 내용을 Claude Code에게 그대로 넘길 수 있는 하나의 프롬프트로 묶습니다. 그게 바로 다음 4장에서 실제 코드를 만들 때 쓸 재료입니다.

[지금 여기]

우리는 22단계를 거쳐 "라이브 투표 서비스"를 직접 만들고, 컨테이너에 담아, AWS 클라우드에 배포합니다. 아래가 그 전체 여정 지도입니다. 지금은 3단계, "무엇을 만들지 기획"에 있습니다.

  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장마무리 (회고 + 리소스 삭제)

이번 장에서 완성되는 것

한 문장으로: 우리가 만들 라이브 투표 서비스가 "무엇을, 어떤 데이터로, 어떤 창구(API)를 통해 동작하는지"를 한 장으로 정리하고, 그 기획을 Claude Code에게 그대로 넘길 하나의 프롬프트로 완성합니다.

이렇게 되면 성공입니다: 이 장 끝의 [프롬프트]를 보면, 기능·데이터·API· 기술 스택·완료 기준이 빠짐없이 한 덩어리로 정리돼 있고, 여러분이 그 내용을 "왜 이렇게 정했는지" 스스로 설명할 수 있습니다.

사전 조건

이 장은 손으로 뭔가를 설치·실행하지 않는 "기획" 장이라, 준비물이 많지 않습니다. 다만 아래가 갖춰져 있어야 이 장의 결과물을 바로 다음 장에서 쓸 수 있습니다.

이 장 자체는 읽고 생각하고 종이(또는 메모장)에 적는 활동이 대부분입니다. 컴퓨터 없이 읽어도 되지만, 중간의 [맛보기]는 직접 손으로 적어 보길 권합니다.

3.1 왜 작게 시작하는가 — MVP

(1) 개념

처음 서비스를 만들 때 흔한 실수는 "이왕 만드는 거 이것저것 다 넣자"입니다. 로그인, 댓글, 알림, 통계, 관리자 페이지… 이렇게 욕심을 내면 완성은 멀어지고, 중간에 지칩니다. 그래서 실무에서는 가장 핵심 기능만 담은 아주 작은 버전을 먼저 만듭니다. 이걸 MVP라고 부릅니다.

용어

MVP(Minimum Viable Product, 최소 기능 제품) "제품이라고 부를 수 있는 최소한의 형태"를 뜻합니다. 즉, 없어서는 안 될 핵심 기능만 담아 일단 동작하게 만든 첫 버전입니다. 나머지 기능은 그다음에 하나씩 붙여 나갑니다.

MVP의 핵심은 "일단 동작하는 가장 작은 것을 빨리 내놓고, 반응을 보며 키운다"입니다. 완벽하게 다 만든 뒤 세상에 내놓는 게 아니라, 뼈대만 세워 먼저 돌려 보는 겁니다.

(2) 활용 사례 — 유명 서비스도 MVP로 시작했다

지금은 거대한 서비스들도 처음엔 놀랄 만큼 작게 시작했습니다.

공통점이 보이나요? 전부 핵심 하나만 남기고 나머지는 뺐다는 점입니다. 그리고 그 하나가 통하는 걸 확인한 뒤에 살을 붙였습니다.

(3) [맛보기] 익숙한 서비스를 MVP로 깎아 보기

개념을 손에 익히기 위해, 우리 투표 서비스와는 별개로 짧게 연습해 봅시다. 종이나 메모장에 적어 보세요.

  1. 여러분이 자주 쓰는 서비스를 하나 고릅니다. (예: 유튜브, 인스타그램, 배달 앱 등)
  2. 그 서비스에서 "이 기능이 없으면 아예 서비스라고 부를 수 없다" 싶은 가장 핵심 기능 딱 하나를 고릅니다.
    • 예: 유튜브 → "영상을 올리고, 그 영상을 재생한다."
    • 예: 배달 앱 → "가게 목록을 보고, 메뉴를 골라 주문한다."
  3. 나머지 기능(댓글, 구독, 추천 알고리즘, 쿠폰, 별점…)은 전부 "나중에 붙일 것" 칸으로 옮깁니다.

이렇게 "핵심 하나 vs. 나중에 붙일 것"으로 나눠 보는 감각이, 바로 아래에서 우리 서비스를 정할 때 그대로 쓰입니다.

(4) 우리 프로젝트에 적용 — 왜 우리도 작게 가나

우리가 MVP로 작게 시작하는 이유는 이 책의 목표와도 맞닿아 있습니다. 이 과정의 진짜 주제는 "화려한 서비스 만들기"가 아니라 "만든 서비스를 Docker와 AWS로 배포하고, 무중단으로 운영하고, 문제가 생기면 롤백하기" 입니다. 그러니 서비스 자체는 배포 흐름을 보여 주기에 딱 좋은 만큼만 작게 만듭니다.

참고

실제로 3부에서 이 작은 서비스에 "새 기능(투표 결과를 퍼센트로 표시)"을 하나 추가해 배포해 봅니다. 그리고 그 과정에서 일부러 문제를 내고, 이전 버전으로 되돌리는(롤백) 실습을 합니다. MVP가 작아야 이 배포·롤백 흐름에 집중할 수 있습니다.

3.2 만들 서비스 정하기 — 라이브 투표

앞 절의 MVP 관점을 우리 서비스에 그대로 적용해 봅시다. 우리가 만들 서비스를 한 문장으로 정의하면 이렇습니다.

질문 하나에 여러 선택지를 두고, 사람들이 투표하면 그 결과를 실시간 막대그래프로 보여 주는 웹 서비스.

MVP 원칙에 따라, 기능을 딱 세 가지로 못 박습니다.

  1. 설문 만들기 — 질문과 선택지 여러 개를 입력해 새 설문을 만든다.
  2. 투표하기 — 선택지 중 하나를 골라 투표한다.
  3. 결과 보기 — 각 선택지가 몇 표 받았는지 막대그래프로 본다.

로그인, 회원가입, 중복 투표 방지, 설문 마감 같은 기능은 일부러 뺍니다. 지금 단계에서는 없어도 "서비스"라고 부를 수 있고, 배포를 배우는 데 지장이 없기 때문입니다. 이렇게 "무엇을 넣고 무엇을 뺄지" 선을 긋는 것이 기획의 핵심입니다. (3.1 [맛보기]에서 "핵심 하나 vs. 나중에 붙일 것"으로 나눠 본 것과 똑같은 작업입니다.)

3.3 화면 흐름과 데이터 모델 스케치

화면 흐름

사용자가 서비스를 어떻게 쓰는지 순서대로 그려 봅니다. 그림 없이 글로만 정리해도 충분합니다.

  1. 설문 만들기 화면: 질문과 선택지를 입력하고 "만들기"를 누른다.
  2. 투표 화면: 만들어진 설문의 선택지들이 보이고, 하나를 눌러 투표한다.
  3. 결과 화면: 투표 직후, 각 선택지의 득표수가 막대그래프로 나타난다.

① 설문 만들기질문점심 뭐 먹지?선택지김치찌개파스타샐러드만들기② 투표하기점심 뭐 먹지?김치찌개파스타샐러드하나를 눌러 투표③ 결과 보기점심 뭐 먹지?김치찌개3파스타5샐러드1막대그래프로 결과만들면투표하면사용자는 이 세 화면만 오간다 — 로그인·회원가입 없이 (MVP)

데이터 모델 — (1) 개념

이제 이 서비스가 다뤄야 할 "데이터"가 무엇인지 생각해 봅시다.

용어

데이터 모델(Data Model) 서비스가 저장하고 다루는 정보의 구조입니다. "어떤 정보를, 어떤 항목으로 나눠 저장할지"를 미리 설계한 밑그림이라고 보면 됩니다. 나중에 이 구조 그대로 데이터베이스(DB)에 표(테이블)로 만들어집니다.

데이터 모델에서 가장 중요한 감각은 "정보를 종류별로 나누고, 서로 어떻게 이어지는지"를 정하는 것입니다. 예를 들어 "설문"과 "선택지"는 서로 다른 종류의 정보이고, "이 선택지들은 저 설문에 딸려 있다"처럼 이어져 있습니다. 한쪽(설문) 하나에 다른 쪽(선택지)이 여러 개 매달리는 이런 관계를, 실무에서 아주 흔하게 봅니다.

(2) 활용 사례 — "하나에 여럿이 딸리는" 관계는 어디에나 있다

방금 말한 "한쪽 하나에 여러 개가 딸리는" 구조는 거의 모든 서비스에 나옵니다.

우리 투표 서비스의 "설문 하나에 선택지 여러 개"도 정확히 같은 모양의 관계입니다. 그래서 이 구조 하나만 이해해 두면, 앞으로 어떤 서비스를 기획하든 데이터를 나누는 감이 잡힙니다.

(3) [맛보기] 주소록을 데이터 모델로 그려 보기

우리 서비스와 별개로, 아주 간단한 예로 손을 풀어 봅시다. "주소록(연락처)" 앱의 데이터 모델을 종이나 메모장에 표로 그려 보세요. 정답은 하나가 아니지만, 아래 정도면 충분합니다.

contacts (연락처)

id name phone
1 홍길동 010-1111-2222
2 김민아 010-3333-4444

포인트는 두 가지입니다. 첫째, 어떤 정보를 저장할지(이름, 전화번호)를 정한다. 둘째, 각 줄을 구분할 고유 번호(id)를 둔다. 이 두 가지가 데이터 모델의 기본 뼈대입니다. 이제 이 감각으로 우리 서비스를 그려 봅시다.

(4) 우리 프로젝트에 적용 — polls / options

우리 서비스에는 두 종류의 정보가 필요합니다.

표로 정리하면 이렇게 됩니다.

polls (설문)

id question created_at
1 점심 뭐 먹지? 2026-07-21

options (선택지)poll_id가 위 pollsid와 이어진다

id poll_id label votes
1 1 김치찌개 3
2 1 파스타 5
3 1 샐러드 1

optionspoll_idpollsid와 이어져 있는 게 보이나요? "이 선택지들은 1번 설문의 보기다"라는 관계를 이렇게 표현합니다. 앞의 [맛보기]에서 본 "쇼핑몰 주문 하나에 상품 여럿", "게시글 하나에 댓글 여럿"과 똑같은 "하나에 여럿" 관계입니다. 지금은 이 정도 감만 잡으면 되고, 실제 DB 테이블로 만드는 건 다음 4장(내 컴퓨터의 DB)과 2부(AWS의 RDS)에서 각각 해 봅니다.

3.4 API 명세 초안 — 화면과 데이터를 잇는 통로

(1) 개념

화면(사용자가 보는 부분)과 데이터(DB에 저장된 정보)는 직접 연결되지 않습니다. 그 사이를 이어 주는 중간 통로가 필요한데, 그게 API입니다.

용어

API(Application Programming Interface) 프로그램끼리 정보를 주고받는 "창구"입니다. 예를 들어 투표 화면이 "3번 선택지에 한 표 넣어 줘"라고 요청하면, 서버가 그 요청을 받아 DB의 표 수를 늘려 줍니다. 이 요청과 응답이 오가는 창구가 API입니다.

용어

엔드포인트(Endpoint) API의 각각의 "창구 주소"입니다. "설문 만들기 창구", "투표하기 창구"처럼 하는 일마다 주소가 하나씩 있습니다. 이 주소로 요청을 보내면 해당 작업이 처리됩니다.

용어

REST 웹(HTTP) 위에서 API를 설계하는 널리 쓰이는 방식(약속)입니다. 요청의 종류를 HTTP 메서드로 정해 두고, 주소는 다루는 대상(설문, 투표 등)을 그대로 표현합니다. 지금은 "API를 정리하는 흔한 규칙" 정도로만 이해하면 됩니다.

REST에서 "무슨 일을 하는 요청인지"는 HTTP 메서드로 구분합니다. 대표적인 것은 다음과 같습니다. (우리는 이 중 앞의 두세 개만 씁니다.)

즉 REST에서는 "주소(무엇을)" + "메서드(어떻게 할지)"의 조합으로 하나의 창구가 정해집니다. 예를 들어 POST /api/polls는 "설문(polls)이라는 대상을 + 새로 만든다(POST)"는 뜻이 됩니다.

(2) 활용 사례 — REST API는 어디에 쓰이나

REST API는 우리 프로젝트에만 쓰는 특별한 게 아니라, 오늘날 거의 모든 인터넷 서비스가 이 방식으로 대화합니다.

이처럼 서로 다른 프로그램이 정보를 주고받아야 할 때, 그 사이의 표준 창구가 바로 API(그중 흔한 방식이 REST)입니다.

(3) [맛보기] 메모 앱의 API를 적어 보기

우리 서비스와 별개로, 아주 간단한 "메모 앱"에 필요한 엔드포인트를 표로 적어 봅시다. "무슨 일 / 메서드 / 주소" 세 칸으로 나눠 종이에 적어 보세요.

하는 일 방식 주소(엔드포인트)
메모 목록 보기 GET /api/memos
메모 하나 작성 POST /api/memos
메모 하나 삭제 DELETE /api/memos/:id

여기서 두 가지를 느껴 보면 됩니다. 첫째, 같은 주소(/api/memos)라도 메서드(GET/POST)가 다르면 다른 일을 합니다(목록 보기 vs. 새로 쓰기). 둘째, 특정 메모 하나를 가리킬 때는 :id처럼 어느 것인지 번호를 주소에 넣습니다. 이 두 규칙이 REST의 핵심 감각입니다. 이제 이 감각으로 우리 서비스의 창구를 정해 봅시다.

(4) 우리 프로젝트에 적용 — 엔드포인트 3개

우리 서비스에 필요한 엔드포인트(창구)를 목록으로 정리해 봅시다.

하는 일 방식 주소(엔드포인트) 설명
설문 만들기 POST /api/polls 질문과 선택지를 받아 새 설문을 만든다
설문 조회 GET /api/polls/:id 특정 설문의 질문과 선택지, 득표수를 가져온다
투표하기 POST /api/polls/:id/vote 고른 선택지에 한 표를 더한다
용어

:id 표기 — 주소 안의 :id는 "여기에 실제 설문 번호가 들어간다"는 자리 표시입니다. 1번 설문을 조회하면 실제로는 /api/polls/1이 됩니다.

세 창구가 3.3의 화면 흐름과 어떻게 맞물리는지 보세요. 설문 만들기 화면은 POST /api/polls를, 투표 화면은 처음에 GET /api/polls/:id로 선택지를 불러온 뒤 투표할 때 POST /api/polls/:id/vote를 씁니다. 이 표가 바로 "API 명세"의 초안입니다. 화면과 데이터가 이 세 개의 창구를 통해 대화한다고 보면 됩니다. 세부 형식은 나중에 Claude Code가 채워 주므로, 지금은 "어떤 창구가 필요한지"만 정하면 충분합니다.

화면 — 사용자 행동API — 화면과 데이터를 잇는 통로데이터 — DB에 저장설문 만들기질문·선택지 입력POST /api/polls새 설문 생성설문 보기설문을 연다GET /api/polls/:id설문·득표수 조회투표하기선택지를 누른다POST /api/polls/:id/vote한 표 더하기데이터베이스polls (설문)id · questioncreated_at1 : Noptions (선택지)id · poll_idlabel · votes화면은 데이터를 직접 만지지 않는다 — 반드시 이 세 창구(API)를 거친다

3.5 완료 기준 정하기

기획의 마지막 조각은 "무엇이 되면 다 만든 걸로 칠 것인가"를 정하는 일입니다. 이걸 완료 기준이라고 합니다.

용어

완료 기준(Acceptance Criteria) "이 조건들이 모두 만족되면 완성으로 인정한다"는 체크 목록입니다. 완료 기준이 있으면 AI에게 "여기까지 되게 해 줘"라고 분명하게 요청할 수 있고, 결과가 제대로 됐는지 나도 확인할 수 있습니다.

우리 투표 서비스의 완료 기준을 이렇게 정합니다.

마지막 항목("새로고침해도 유지")이 중요합니다. 데이터가 DB에 제대로 저장돼야 만족되는 조건이라, 뒤에서 DB를 붙이는 이유와 자연스럽게 이어집니다.

3.6 이 기획을 Claude Code에 전달하기

지금까지 정리한 것 — MVP 범위, 세 가지 기능, 데이터 모델, API 목록, 완료 기준 — 을 하나의 프롬프트로 묶으면, 그게 바로 4장에서 쓸 "좋은 프롬프트"가 됩니다. 아래 [프롬프트]가 그 완성본입니다. 4장에서 이걸 vote-app 폴더에서 실행한 Claude Code에 그대로 붙여넣을 것이므로, 지금은 내용이 빠짐없이 맞는지 눈으로 확인해 두면 됩니다. 그대로 써도 되고, 여러분 방식대로 다듬어도 됩니다.

프롬프트

기획 전달 (4장에서 Claude Code에 넣을 최종본)

라이브 투표 웹 서비스를 만들 거야. 아직 코드는 만들지 말고,
먼저 전체 구조와 만들 순서를 계획해서 설명해 줘.

[기능]
1. 설문 만들기: 질문 하나와 선택지 여러 개를 입력해 설문을 만든다
2. 투표하기: 선택지 중 하나를 골라 투표한다
3. 결과 보기: 선택지별 득표수를 막대그래프로 본다

[데이터]
- polls(id, question, created_at)
- options(id, poll_id, label, votes)

[필요한 API]
- POST /api/polls        : 설문 만들기
- GET  /api/polls/:id    : 설문 조회
- POST /api/polls/:id/vote : 투표하기

[기술 스택]
- 프론트엔드: React (Vite)
- API 서버: Node.js (Express)
- 데이터베이스: PostgreSQL

[완료 기준]
- 설문을 만들고, 투표하고, 결과가 막대그래프로 보인다
- 새로고침해도 투표 결과가 유지된다
참고

왜 스택(React, Express, PostgreSQL)까지 적어 주나요? 이걸 지정하지 않으면 AI가 알아서 고릅니다. 하지만 우리는 뒤에서 이 서비스를 Docker로 담고 AWS에 배포할 건데, 그 실습이 이 스택 기준으로 준비돼 있습니다. 그래서 미리 못 박아 둡니다. - [용어] 기술 스택(Tech Stack): 서비스를 만드는 데 쓰는 기술들의 묶음입니다. "프론트는 React, 서버는 Express, DB는 PostgreSQL"처럼 각 부분에 어떤 도구를 쓸지 정한 것입니다. [참고] 이 프롬프트는 어디에 보관하나 지금 이 [프롬프트]를 4장에서 다시 씁니다. 잊지 않도록, VS Code에서 vote-app 폴더를 열고 그 안에 기획.md 같은 메모 파일을 하나 만들어 위 내용을 붙여넣어 두면 편합니다. (파일을 안 만들어도 됩니다. 이 책의 3.6절을 다시 펴서 그대로 써도 똑같습니다.)

[확인]

이번 장이 제대로 끝났는지 확인합니다. 이 장은 화면 출력이 아니라 "기획이 머릿속과 종이에 정리됐는지"로 확인합니다. 아래 질문에 스스로 답해 보세요.

이 질문들에 막힘없이 답할 수 있으면, 기획이 끝난 것입니다.

막히면

이 장에서 초보자가 자주 갸웃하는 지점과 대처법입니다.

[체크리스트]

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

이제 무엇을 만들지가 분명해졌습니다.