AI 개발

바이브코딩으로 만든 서비스, 배포가 안 되는 이유 5가지

localhost에서는 잘 되는데 운영 서버에 올리는 순간 깨지는 이유를 환경변수, 빌드, 데이터베이스, 도메인·HTTPS, 배포 파이프라인 관점에서 단계별로 설명합니다.

2026.09.24 · 예상 읽기 10분 · 완주 에디터 · 조회 12

AI 코딩 도구를 쓰면 화면을 만드는 속도는 놀랄 만큼 빨라졌습니다. 로그인 화면, 검색, 게시판, 예약 폼 정도는 하루나 이틀 만에도 만들어집니다. 그런데 “내 컴퓨터에서는 잘 된다”와 “실제 고객이 인터넷에서 안정적으로 쓴다” 사이에는 전혀 다른 종류의 일이 남아 있습니다. 이 차이를 이해하지 못하면 프로젝트는 70~80%까지는 빠르게 가다가 배포 직전에 멈춥니다.

완주에서 말하는 “마지막 20%”는 단순히 서버에 파일을 올리는 작업이 아닙니다. 운영 환경에 필요한 설정을 분리하고, 데이터가 사라지지 않게 만들고, 도메인과 인증서를 연결하고, 다시 수정해도 서비스가 무너지지 않는 배포 흐름을 만드는 과정입니다.

먼저 구분해야 할 것: 개발 환경과 운영 환경

개발 환경은 내가 고치기 편한 환경입니다. 오류 메시지를 크게 보여줘도 되고, 테스트 계정을 써도 되고, 데이터가 조금 날아가도 다시 만들 수 있습니다. 반면 운영 환경은 고객이 쓰는 환경입니다. 서버가 재시작되어도 데이터가 남아야 하고, 비밀키가 노출되면 안 되며, 로그인과 결제는 실제 계정으로 동작해야 하고, 장애가 나면 원인을 추적할 로그가 있어야 합니다.

바이브코딩 프로젝트가 배포에서 막히는 이유는 대부분 “코드 자체가 틀려서”라기보다 이 두 환경의 차이를 설계하지 않았기 때문입니다.

이유 1. 내 컴퓨터에만 있는 환경변수와 비밀값

API 키, 데이터베이스 주소, 이메일 발송 키, 소셜 로그인 키, 결제 시크릿 키 같은 값은 코드에 직접 넣으면 안 됩니다. 개발할 때는 .env 파일이나 IDE 설정에 들어 있어 정상적으로 동작하지만, 서버에는 그 파일이 없거나 값이 다릅니다.

대표적인 증상은 다음과 같습니다.

  • 로컬에서는 로그인되는데 서버에서는 401, invalid key, missing secret 오류가 난다.
  • AI API 호출이 운영에서만 실패한다.
  • 결제 테스트는 되는데 라이브 키로 바꾸는 순간 실패한다.
  • 서버 재배포 후 갑자기 외부 API 연결이 끊긴다.

어떻게 점검할까

  1. 코드에서 process.env, os.getenv, import.meta.env처럼 외부 설정을 읽는 부분을 찾습니다.
  2. “개발용 값”과 “운영용 값”을 구분합니다.
  3. 운영 플랫폼의 Secret/Environment Variables 메뉴에 값을 등록합니다.
  4. 브라우저로 내려가면 안 되는 시크릿 키가 클라이언트 코드에 포함되지 않았는지 확인합니다.
  5. Git 저장소에 .env, 서비스 계정 JSON, 개인키가 커밋되어 있지 않은지 점검합니다.

핵심은 “코드는 같고 설정만 환경마다 바뀌게” 만드는 것입니다. 운영 서버를 바꿀 때마다 소스 코드를 수정해야 한다면 아직 배포 구조가 정리되지 않은 상태입니다.

이유 2. 개발 서버에서는 되지만 Production Build에서 실패

React, Next.js, Vue, Flutter Web 같은 프레임워크는 개발 모드와 실제 배포용 빌드가 다릅니다. 개발 모드는 빠른 수정과 디버깅을 위해 비교적 관대하지만, 배포 빌드는 타입 오류, 누락된 모듈, 잘못된 import, 서버 전용 코드의 브라우저 실행 같은 문제를 더 엄격하게 드러냅니다.

AI가 여러 번 파일을 고치면서 다음 문제가 흔히 쌓입니다.

  • 쓰지 않는 코드와 오래된 컴포넌트가 남아 있음
  • 같은 기능이 두 군데 구현되어 있음
  • 서버에서만 존재하는 환경변수를 브라우저에서 사용함
  • 대소문자 파일명이 로컬 macOS에서는 통과하지만 Linux 서버에서 실패함
  • 빌드 명령어와 실행 명령어가 정확히 정의되지 않음

배포 전에 반드시 해볼 것

운영 서버에 올리기 전에 로컬에서도 “운영과 같은 방식”으로 빌드해 보세요. 예를 들어 Node 기반이라면 npm run build가 먼저 성공해야 합니다. 빌드가 실패하는 상태에서 배포 플랫폼 설정을 만지기 시작하면 원인을 코드와 인프라 사이에서 계속 잘못 찾게 됩니다.

이유 3. 데이터베이스가 ‘개발용 상태’에 머물러 있음

초기 프로토타입은 SQLite, 브라우저 LocalStorage, 임시 JSON, 개발용 Supabase 프로젝트처럼 가볍게 시작할 수 있습니다. 문제는 고객이 쓰기 시작하면 데이터가 서비스의 자산이 된다는 점입니다.

운영 DB에서 확인해야 할 것은 최소한 다음입니다.

  • 운영용 DB가 개발 DB와 분리되어 있는가
  • 테이블 스키마 변경을 반복 가능한 방식으로 적용할 수 있는가
  • 백업이 존재하고 실제 복구가 가능한가
  • 관리자 실수로 전체 데이터가 삭제되지 않도록 권한이 나뉘어 있는가
  • 개인정보나 결제 관련 데이터가 필요 이상으로 저장되고 있지 않은가

특히 AI가 코드를 수정하면서 테이블 구조까지 계속 바꾸면 “내 로컬 DB에는 컬럼이 있는데 운영 DB에는 없는” 상황이 자주 생깁니다. 이를 막는 것이 migration입니다. migration은 데이터베이스 구조 변경을 파일과 버전으로 관리하는 방식입니다.

이유 4. 도메인, DNS, HTTPS는 코드 밖의 문제다

도메인을 샀다고 바로 서비스 주소가 만들어지는 것은 아닙니다. 도메인의 DNS 레코드가 실제 서버를 가리켜야 하고, 서버는 해당 도메인을 받아들이도록 설정되어야 하며, HTTPS 인증서까지 정상적으로 발급되어야 합니다.

대표적인 문제는 다음과 같습니다.

  • www는 되는데 루트 도메인은 안 됨
  • 이전 서버의 DNS 레코드가 남아 있음
  • HTTPS는 켜졌는데 API는 HTTP라 브라우저가 차단함
  • 소셜 로그인 Redirect URL에 운영 도메인이 등록되지 않음
  • 쿠키가 localhost 기준으로 설정되어 운영에서 유지되지 않음

여기서 중요한 점은 도메인 연결을 프로젝트 마지막 날에 하지 않는 것입니다. 첫 주나 둘째 주에 임시라도 운영 URL을 확보해 놓으면 로그인, 결제, 이메일, OAuth처럼 “진짜 주소가 있어야 테스트할 수 있는 기능”을 미리 확인할 수 있습니다.

이유 5. 한 번 올리는 것은 배포가 아니다

첫 배포에 성공했다고 끝이 아닙니다. 실제 서비스는 오픈한 다음날 바로 수정 요청이 생깁니다. 문구 하나, 가격 하나, 가입 폼 하나를 고쳤는데 다시 서버에 올리는 과정이 수동이라면 배포할 때마다 장애 위험이 생깁니다.

최소한의 반복 배포 구조는 아래와 같습니다.

코드 수정 → 테스트 → Git 커밋 → main 반영 → 자동 빌드 → 배포 → 헬스체크

이 흐름이 만들어지면 대표가 AI에게 수정 요청을 한 뒤에도 “이번 수정 때문에 전체 서비스가 내려갈까?”라는 공포가 크게 줄어듭니다.

실제로는 어떤 순서로 배포해야 할까

배포가 처음이라면 다음 순서가 가장 안전합니다.

  1. 현재 코드 정리 — 실행되는 버전을 하나로 고정합니다.
  2. Git 저장 — 잘 되는 상태를 커밋합니다.
  3. 운영 빌드 성공 확인 — 로컬에서 production build를 통과시킵니다.
  4. 운영 DB 생성 — 스키마와 초기 데이터를 적용합니다.
  5. 서버/호스팅 연결 — 임시 도메인으로 먼저 띄웁니다.
  6. 환경변수 등록 — API, DB, 인증, 결제 값을 연결합니다.
  7. 도메인·HTTPS 연결 — 실제 서비스 URL을 만듭니다.
  8. 로그인·결제·메일 등 외부 서비스의 운영 URL 설정 — Redirect/Webhook 주소를 운영 기준으로 바꿉니다.
  9. 로그·백업 확인 — 장애와 데이터 손실에 대비합니다.
  10. 작은 수정 한 번을 실제 배포 — 반복 가능한지 확인합니다.

오류 증상으로 빠르게 원인 찾기

증상 먼저 볼 곳
페이지 자체가 안 열림 DNS, 서버 상태, 배포 로그
화면은 열리는데 API 호출 실패 환경변수, CORS, API URL
로그인만 실패 Redirect URL, 쿠키, Auth 키
새 가입자는 되는데 기존 데이터 없음 운영 DB 연결 여부
결제 후 주문 상태가 안 바뀜 서버 승인 처리, Webhook
배포 직후만 되고 재시작하면 데이터 사라짐 로컬 파일 저장 여부
새 코드가 반영되지 않음 Git 브랜치, 자동 배포 대상 브랜치

“배포 완료”의 최소 기준

완주에서는 URL이 열리는 것만으로 배포 완료라고 보지 않습니다. 최소한 다음 상태를 목표로 합니다.

  • 고객이 접속할 고정 도메인이 있다.
  • HTTPS가 정상이다.
  • 운영 DB와 백업 정책이 있다.
  • 중요한 Secret이 코드 밖에서 관리된다.
  • 로그인/결제/메일 등 외부 연동이 운영 환경에서 확인됐다.
  • 오류를 볼 수 있는 로그가 있다.
  • Git에서 이전 버전으로 돌아갈 수 있다.
  • 작은 수정 후 재배포가 반복 가능하다.

정리

바이브코딩의 강점은 “시작 비용”을 크게 낮춘 것입니다. 하지만 운영 가능한 서비스가 되려면 여전히 환경, 데이터, 보안, 배포라는 시스템적 사고가 필요합니다. 그렇다고 모든 인프라를 대기업 수준으로 만들 필요도 없습니다. 초기 서비스에 중요한 것은 과하지 않은 운영 기준을 만들고, 대표가 이후 수정할 수 있을 만큼 단순하게 유지하는 것입니다.

완주 관점의 핵심: 첫 배포가 목표가 아니라 두 번째 배포를 혼자 할 수 있는 상태가 목표입니다.

읽고도 어디서부터 손대야 할지 모르겠다면

완주는 교육보다 실제 프로젝트와 실제 업무를 기준으로 현재 막힌 지점을 진단합니다. 무엇을 더 만들지가 아니라 무엇을 먼저 끝낼지부터 정합니다.