배포할 때 .env를 그대로 넣어도 될까요? 개발·운영 데이터베이스를 나눠야 하는 이유

로컬과 배포 환경이 같은 데이터베이스를 사용하면 테스트·삭제·스키마 변경이 실제 고객 데이터에 영향을 줄 수 있어요. 개발용과 운영용 DB를 나누고 같은 환경변수 이름에 환경별 다른 값을 설정해 운영 데이터는 보호해야 합니다.

핵심 요약

바이브코딩으로 만든 서비스를 처음 배포할 때 이런 과정을 거칩니다.

1. 내 컴퓨터의 .env 파일을 연다.
2. DATABASE_URL을 복사한다.
3. Vercel 환경변수 화면에 붙여넣는다.
4. 배포한다.

배포된 서비스에서 데이터가 잘 저장되면 모든 설정이 끝난 것처럼 보여요. 하지만 개발할 때도 같은 DATABASE_URL을 계속 사용한다면 내 컴퓨터와 실제 서비스가 하나의 데이터베이스를 함께 쓰게 됩니다.

        같은 데이터베이스
           ↑       ↑
      내 컴퓨터   실제 서비스

사용자가 없고 테스트 데이터만 있을 때는 큰 문제가 없어 보입니다. 실제 사용자가 들어온 뒤에도 이 구조를 유지하면 개발 중 만든 가짜 데이터가 운영 화면에 나타나거나, 테스트를 위한 삭제가 실제 데이터에 영향을 줄 수 있어요.

핵심부터 말하면 .env에 있는 값을 Vercel에 입력하는 행위 자체가 문제는 아닙니다. 개발 환경과 운영 환경에 같은 데이터베이스 값을 넣는 것이 문제예요.

이 글에서는 환경에 따라 데이터베이스를 왜 나누는지, 이미 하나를 함께 쓰고 있다면 어떻게 분리할지 알아볼게요.

환경변수와 .env의 기본 역할이 아직 낯설다면 API 키와 .env 설명을 먼저 읽어도 좋습니다.

환경변수는 값을 한 번 저장해 복사하는 곳이 아니에요

.env 파일에는 다음처럼 이름과 값이 들어 있습니다.

DATABASE_URL=postgresql://...
SITE_URL=http://localhost:3000
RESEND_API_KEY=re_...

코드는 실제 데이터베이스 주소를 직접 적지 않고 DATABASE_URL이라는 이름을 사용합니다. 프로그램이 실행될 때 현재 환경에 등록된 값을 읽어요.

코드
→ DATABASE_URL이라는 이름을 사용

개발 환경
→ 개발 DB 주소를 넣음

운영 환경
→ 운영 DB 주소를 넣음

환경변수 이름은 같아도 값은 달라질 수 있습니다. 이것이 이름에 “환경”이 붙은 이유예요.

사이트 주소도 로컬에서는 http://localhost:3000이지만 운영에서는 실제 도메인을 사용합니다. 결제도 개발할 때는 테스트 키를 사용하고 실제 서비스에서는 운영 키를 사용해요. 데이터베이스 역시 같은 원리로 나눌 수 있습니다.

개발 환경
DATABASE_URL=개발용 데이터베이스 주소

운영 환경
DATABASE_URL=운영용 데이터베이스 주소

코드를 두 벌로 만들 필요는 없습니다. 같은 코드가 실행되는 환경에 맞는 서비스로 연결되도록 값만 다르게 설정하는 것입니다.

같은 데이터베이스를 쓰면 어떤 일이 생길까요?

개발과 운영이 하나의 DB를 공유해도 조회만 한다면 당장 문제가 보이지 않을 수 있습니다. 하지만 기능을 만드는 과정에서는 데이터를 계속 만들고, 바꾸고, 지웁니다.

테스트 데이터가 실제 서비스에 섞여요

신청 기능을 테스트하려고 다음 내용을 입력했다고 해볼게요.

이름: 테스트
전화번호: 01000000000
신청 상태: 결제 완료

개발 화면과 운영 화면이 같은 DB를 보면 이 가짜 신청도 관리자 화면에 나타납니다. 실제 신청자 수와 매출 집계에 포함될 수도 있어요.

삭제 테스트가 실제 데이터를 지울 수 있어요

AI에게 “테스트하면서 만든 신청 데이터를 전부 지워줘”라고 요청할 수 있습니다. AI는 현재 연결된 DB가 운영용인지 모른 채 이름이나 날짜를 기준으로 데이터를 삭제할 수 있어요.

개발용이라고 생각하고 실행한 삭제
→ 실제 사용자의 운영 데이터에 적용

코드의 오류보다 더 위험한 점은 명령 자체는 정상적으로 성공할 수 있다는 것입니다. 데이터가 지워진 뒤에야 잘못된 연결을 알아차릴 수 있어요.

테이블 구조 변경이 실제 서비스를 멈출 수 있어요

새 기능을 만들면서 컬럼 이름을 바꾸거나 테이블을 다시 만들 수 있습니다. 개발 중인 코드는 새 구조를 사용하지만 현재 운영 중인 코드는 이전 구조를 사용하고 있을 수 있어요.

두 코드가 같은 DB를 바라보는 상태에서 구조를 먼저 바꾸면 실제 서비스가 찾던 컬럼이 사라져 오류가 날 수 있습니다.

알림과 외부 작업까지 이어질 수 있어요

DB에 주문이 저장되면 이메일이나 문자가 발송되고 결제 확인이 실행되는 구조도 있습니다. 개발 중 넣은 가짜 데이터가 실제 알림이나 업무 자동화를 시작할 수 있어요.

그래서 데이터베이스만 나누고 이메일·결제 키는 그대로 쓰는 것도 충분하지 않을 수 있습니다. 환경별로 어떤 외부 서비스가 연결되는지 함께 확인해야 해요.

개발과 운영은 역할이 달라요

Vercel에서는 개발과 운영에 서로 다른 환경변수를 설정할 수 있어요. (Vercel 환경 설명 (새 탭에서 열림), Vercel 환경변수 문서 (새 탭에서 열림))

Development

내 컴퓨터에서 기능을 만드는 환경입니다. 실패해도 실제 사용자에게 영향을 주지 않아야 해요.

localhost
→ 개발용 DB
→ 테스트 데이터
→ 테스트 결제와 테스트 알림

Production

실제 사용자가 들어오는 운영 환경입니다. 실제 데이터와 운영용 비밀값을 사용합니다.

실제 도메인
→ 운영 DB
→ 실제 사용자 데이터
→ 운영 결제와 운영 알림

두 환경의 코드는 거의 같을 수 있어요. 달라지는 것은 연결할 데이터베이스, 사이트 주소, 결제 모드, 알림 대상 같은 설정입니다.

가장 단순한 구조는 개발 DB와 운영 DB 두 개예요

작은 프로젝트라면 다음 두 개로 시작할 수 있어요.

localhost 개발
→ 개발용 데이터베이스

실제 서비스
→ 운영용 데이터베이스

개발용 DB에는 가짜 사용자와 테스트 주문을 자유롭게 만들 수 있습니다. 데이터를 지우고 다시 넣어도 실제 서비스에 영향을 주지 않아요.

운영용 DB에는 실제 사용자의 데이터만 저장합니다. 개발 도구가 기본적으로 접근하지 않게 합니다.

환경이 많을수록 무조건 좋은 것은 아닙니다. 관리할 주소와 키, 데이터 준비 작업도 함께 늘어나요. 중요한 것은 개수가 아니라 운영 데이터를 개발 작업으로부터 격리하는 것입니다.

Supabase에서는 어떻게 나눌까요?

Supabase를 사용한다면 몇 가지 방법이 있습니다.

개발용과 운영용 프로젝트를 따로 만들기

이해하기 가장 쉬운 방식입니다.

my-app-dev
→ 개발

my-app-prod
→ 운영

각 프로젝트는 서로 다른 데이터베이스 주소와 API 키를 가집니다. 개발 프로젝트에서 테이블을 바꾸거나 데이터를 삭제해도 운영 프로젝트에는 바로 영향을 주지 않아요.

로컬 Supabase 사용하기

Supabase CLI를 사용해 내 컴퓨터에 로컬 개발 환경을 실행할 수도 있습니다. 인터넷의 개발용 DB를 공유하지 않고 개인 환경에서 테스트하고 싶을 때 사용할 수 있어요.

어떤 방법을 선택하든 원칙은 같습니다.

개발 작업은 격리된 DB에서 확인
→ 검토된 구조 변경만 운영 DB에 반영

서버에서 Supabase PostgreSQL에 직접 연결하는 구조는 Supabase를 데이터베이스로 추천하는 이유에서 더 자세히 설명했습니다.

DB를 나누면 테이블 구조는 어떻게 맞출까요?

개발용과 운영용 DB를 따로 만들면 새로운 문제가 생깁니다.

개발 DB에는 memo 컬럼이 있는데
운영 DB에는 아직 없다면?

두 데이터베이스의 구조를 같은 순서로 바꾸기 위해 마이그레이션을 사용합니다.

1. 개발 DB에서 구조 변경
2. 마이그레이션 파일 생성
3. 개발 기능과 기존 데이터 영향 테스트
4. 코드를 Git에 기록하고 검토
5. 배포 시 운영 DB에 같은 마이그레이션 적용

개발 DB 전체를 운영 DB에 복사하는 것이 아닙니다. 어떤 테이블과 컬럼을 어떻게 바꿀지 적은 변경 기록을 운영에 적용하는 거예요.

개발 데이터
→ 운영에 복사하지 않음

검토된 구조 변경 기록
→ 운영에 적용

마이그레이션 파일 생성과 실제 DB 적용이 왜 다른지는 스키마와 마이그레이션 설명에서 확인할 수 있습니다.

개발에서 확인한 마이그레이션을 main에 올릴 때 운영 DB에도 자동으로 적용하려면 GitHub Actions로 운영 DB 마이그레이션을 자동화하는 방법을 이어서 보세요.

운영 데이터를 개발 DB에 복사해도 될까요?

개발 환경에서도 실제와 비슷한 데이터가 있으면 테스트하기 편해 보입니다. 하지만 운영 DB에는 이름, 이메일, 전화번호, 주문 정보 같은 개인정보가 들어 있을 수 있어요.

운영 데이터를 그대로 내려받아 개인 컴퓨터나 접근자가 많은 개발 DB에 복사하면 데이터가 노출되는 범위가 넓어집니다.

개발 DB에는 가능하면 직접 만든 가짜 데이터를 넣으세요.

실제 이름 대신 테스트 사용자
실제 전화번호 대신 테스트 번호
실제 결제 대신 테스트 결제
실제 이메일 발송 대신 차단된 수신처

운영 데이터의 형태가 꼭 필요하다면 개인정보를 알아볼 수 없게 바꾸는 과정과 조직의 데이터 처리 기준이 필요합니다. 단순히 편하다는 이유로 운영 DB를 복사하면 안 됩니다.

Vercel에는 같은 이름으로 다른 값을 넣어요

Vercel 프로젝트에서 DATABASE_URL을 추가할 때 적용할 환경을 선택할 수 있습니다.

DATABASE_URL

Development → 개발 DB 주소
Production  → 운영 DB 주소

각 환경에 변수 이름을 다르게 만들 필요는 없어요.

DATABASE_URL_DEV
DATABASE_URL_PROD

처럼 여러 이름을 코드에서 직접 나누기보다, 보통은 DATABASE_URL 하나를 두고 Vercel이 현재 환경에 맞는 값을 제공하게 합니다. 그러면 코드에 “지금 운영이면 이 값을 사용해” 같은 조건문을 추가하지 않아도 돼요.

Vercel에서 환경변수 값을 바꾼 뒤에는 새 배포부터 변경이 적용됩니다. 기존 배포에는 자동으로 새 값이 들어가지 않으므로 재배포와 확인이 필요해요. (Vercel 환경변수 문서 (새 탭에서 열림))

로컬 .env.env.local은 GitHub에 올리지 않습니다. .gitignore에 포함되어 있는지 확인하고, 운영 DB 비밀번호가 코드나 문서에 들어갔다면 삭제만 하지 말고 비밀번호와 키를 교체해야 해요.

언제부터 반드시 나누는 게 좋을까요?

사용자도 없고 데이터도 모두 지워도 되는 초기 실험이라면 하나의 DB로 빠르게 검증할 수 있습니다. 화면 하나를 만들어보는 단계부터 데이터베이스를 여러 개 운영해야 한다는 뜻은 아니에요.

다만 다음 중 하나라도 해당하면 분리를 우선 검토해야 합니다.

특히 실제 사용자 데이터가 생긴 뒤에는 “나중에 나누자”는 결정의 비용이 계속 커집니다. 데이터베이스 주소뿐 아니라 인증 사용자, 파일 저장소, 외부 자동화도 함께 옮겨야 할 수 있기 때문입니다.

이미 하나의 DB를 함께 쓰고 있다면

급하게 운영 DB 연결을 끊기보다 현재 구조부터 확인하세요.

1. 지금 DB를 운영용으로 지정해요

이미 실제 데이터가 들어 있다면 현재 데이터베이스를 운영용으로 두는 편이 단순할 수 있습니다. 먼저 백업과 복구 방법을 확인하세요.

2. 개발용 DB를 새로 만들어요

별도의 Supabase 프로젝트나 로컬 DB를 준비합니다. 운영 데이터를 복사하기보다 마이그레이션을 사용해 같은 테이블 구조를 만드세요.

3. 가짜 개발 데이터를 넣어요

기능을 확인할 수 있는 테스트 사용자, 신청, 주문을 준비합니다. 이런 초기 데이터를 넣는 작업을 시드(seed)라고 부르기도 해요.

4. 환경별 값을 바꿔요

로컬 .env.local → 개발 DB
Vercel Production → 기존 운영 DB

데이터베이스 주소뿐 아니라 Supabase URL과 키, 파일 저장소, 결제·이메일 설정도 함께 확인하세요.

5. 새로 배포하고 행동별로 확인해요

환경을 분리한 뒤에는 테스트 데이터 하나를 만들어 어느 DB에 들어가는지 직접 확인하는 것이 좋습니다.

AI에게 환경 분리를 점검시키는 프롬프트

AI에게 운영 DB 주소가 포함된 화면이나 파일을 그대로 보여주며 보고서를 만들게 할 필요는 없습니다. 비밀값은 출력하지 않고, 서로 같은 대상을 가리키는지만 안전하게 비교하게 하세요.

이 프로젝트의 개발·운영 환경이
같은 데이터베이스를 공유하는지 읽기 전용으로 점검해줘.

아직 코드, 데이터베이스, Vercel 설정을 변경하지 마.
환경변수의 실제 값과 비밀번호는 응답에 절대 출력하지 마.

다음을 실제 프로젝트 파일과 내가 제공하는 배포 설정을 근거로 확인해줘.

1. 데이터베이스 연결을 만드는 파일과 사용하는 환경변수 이름
2. 로컬에서 읽는 .env 파일 종류와 Git 추적 여부
3. Vercel Development·Production에 필요한 환경변수 목록
4. 각 환경이 같은 DB인지 다른 DB인지
   전체 주소나 비밀번호 대신 안전하게 가린 호스트·프로젝트 식별 정보만 사용
5. Supabase Auth·Storage·API 키도 환경별로 분리되어 있는지
6. 결제·이메일·문자·외부 API가 테스트용과 운영용으로 나뉘는지
7. 마이그레이션 파일과 개발·운영 DB의 적용 상태
8. 테스트 데이터를 만드는 seed 방식
9. 현재 구조를 분리할 때 데이터 손실이나 서비스 중단 위험

결과는 다음 표로 정리해줘.
항목 | Development | Production | 확인한 근거 | 위험 | 권장 조치

확인하지 못한 항목은 추측하지 말고 확인 불가로 표시해줘.
마지막에는 운영 DB를 그대로 유지하면서 개발 환경부터 분리하는
단계별 계획만 제안하고, 내 승인 전에는 실행하지 마.

Vercel 대시보드에 AI가 접근할 수 없다면 각 환경에서 변수 이름이 보이는 화면을 확인하고, 값은 노출하지 않은 채 어떤 프로젝트를 가리키는지만 알려주세요.

정리

환경변수를 나누는 이유는 코드를 다르게 만들기 위해서가 아닙니다. 같은 코드가 실행되는 환경에 맞는 데이터베이스와 외부 서비스에 연결되게 하기 위해서예요.

개발은 마음껏 실패할 수 있는 곳으로
운영은 실제 데이터를 지켜야 하는 곳으로

이 경계를 만들면 AI에게 기능 추가와 데이터 변경을 맡길 때도 무엇을 안전하게 시험할 수 있고 무엇은 보호해야 하는지 훨씬 분명해집니다.

환경변수 설정과 배포 전 보안 확인은 바이브코딩 가이드 12장의 보안 점검13장의 배포 실습을 참고하세요.

#운영#환경변수#데이터베이스#배포#Vercel#Supabase#마이그레이션#바이브코딩

인스타그램 @ddukddak.build · 페이스북 뚝딱