본문으로 건너뛰기

Prisma 기반 DB 스키마 운영 가이드

1. 개요

본 문서는 DB Schema Migration 정책을 준수하여, Prisma ORM을 사용하는 환경에서 마이그레이션 파일 기반의 스키마를 관리하고 배포하는 구체적인 절차를 안내합니다.

2. 환경 설정 (Local)

Prisma CLI 명령어를 실행하기 전, 타겟이 되는 데이터베이스에 연결하기 위해 .env 파일에 DATABASE_URL을 올바르게 설정해야 합니다.

  • .env 파일 생성: 프로젝트 루트(libs/core/database/prisma)에 .env 파일을 생성합니다.

    • .env 파일은 Git에 커밋되지 않도록 .gitignore에 반드시 추가해야 합니다.
  • DATABASE_URL 설정: 로컬 개발용 PostgreSQL 데이터베이스의 연결 문자열을 설정합니다.

    DATABASE_URL="postgresql://[사용자명]:[비밀번호]@[호스트명]:[포트]/[데이터베이스명]?schema=public"
  • .gitignore 확인: .env 파일이 .gitignore에 잘 등록되어 있는지 확인하여 민감 정보가 Git 저장소에 올라가지 않도록 합니다.

3. 파일 및 디렉토리 구조

libs/core/database/ 하위에서 관리됩니다.

database
│ └── prisma/
│ │ └── migrations/
│ │ └── schema.prisma
│ │ └── .env
│ └── schemas/
│ └── scripts/
│ └── build-schema.js
  • schema.prisma: build-schema 스크립트에 의해 자동 생성된 통합 스키마 파일입니다.
  • migrations/: 시간 순서대로 생성된 모든 마이그레이션 이력(SQL) 파일들이 저장됩니다.
  • deployments/: 환경별/앱별 배포 상태를 추적하는 JSON 파일들이 위치합니다.
    • apps.json: 각 애플리케이션이 요구하는 마이그레이션 ID 정보.
    • environments.json: 각 DB 인스턴스의 마이그레이션 적용 상태.

4. 개발 워크플로우

본 프로젝트는 중앙화된 마이그레이션 생성 방식을 채택하여, 여러 개발자가 동시에 작업할 때 발생할 수 있는 타임스탬프 기반 마이그레이션 ID 충돌을 방지합니다.

4.1 Phase 1: 스키마 변경 제안

개발자는 로컬에서 스키마 파일만 수정하고, 마이그레이션 파일 생성은 Workflow에 위임합니다.

  1. 스키마 수정: libs/core/database/schemas/ 하위의 해당 도메인 폴더 내 .prisma 파일을 수정합니다.

  2. 통합 스키마 빌드: 개별 스키마 파일들을 병합하여 schema.prisma를 생성합니다.

    yarn db:build-schema
  3. Git 커밋 및 푸시: 스키마 파일만 커밋합니다.

    git add libs/core/database/schemas/
    git add libs/core/database/prisma/schema.prisma
    git commit -m "feat: update user schema to add profile fields"
    git push origin feature/add-user-profile
  4. PR 생성: release 브랜치를 타겟으로 PR을 생성합니다.

4.2 Phase 2: 마이그레이션 생성 요청 및 검토

개발자는 PR에서 Workflow를 통해 마이그레이션을 생성하고, 결과를 검토합니다.

  1. 스키마 변경사항 확인 (Diff):

    • PR이 생성되면 Bot이 게시한 prisma migrate diff 결과를 확인하여 의도한 변경인지 1차 검증합니다.
  2. 마이그레이션 생성 요청:

    • Diff 확인 후 이상이 없으면 PR Comment로 마이그레이션 생성을 요청합니다.
    • 명령어: /create-migration <migration_name>
      • 예: /create-migration add_user_profile_fields
  3. 생성된 마이그레이션 검토:

    • Workflow가 마이그레이션 파일을 생성하여 PR 브랜치에 커밋하면, 변경된 파일(migration.sql)을 확인합니다.
    • SQL 문이 의도한 대로 생성되었는지, 데이터 손실 가능성은 없는지 검토합니다.
  4. 수정 및 재요청 (필요 시):

    • SQL 수정이 필요한 경우 로컬에서 git pull 후 직접 수정하여 커밋하거나, 스키마를 수정하고 마이그레이션을 재생성합니다.

4.3 Phase 3: 배포 요청

리뷰 승인이 완료되면 배포를 요청합니다.

  1. 배포 명령:

    • PR Comment로 배포를 요청합니다.
    • 명령어: /deploy <env> (예: /deploy dev, /deploy prod)
  2. 배포 결과 확인:

    • Workflow의 배포 성공 여부를 확인합니다.
    • 배포 성공 시 PR이 자동으로 머지되거나, 수동으로 머지합니다.

5. 배포 시스템 및 자동화

Workflow가 내부적으로 어떻게 동작하여 마이그레이션을 안전하게 생성하고 배포하는지 설명합니다.

5.1 시스템 아키텍처 및 흐름

5.2 상세 프로세스 (GitHub Actions)

5.2.1 자동 검증 (PR 생성 시)

  • 트리거: PR 생성 또는 스키마 파일 변경 시
  • 동작:
    1. schema.prisma 빌드 및 유효성 검사
    2. 타겟 DB(DATABASE_URL)와 현재 스키마를 비교 (migrate diff)
    3. 데이터 손실 경고(Warnings)나 변경 SQL을 PR Comment로 게시

5.2.2 마이그레이션 생성 (/create-migration)

  • 트리거: PR Comment 명령어
  • 동작:
    1. 개발자가 입력한 마이그레이션 이름 파싱
    2. Shadow DB(또는 Dev DB)를 사용하여 prisma migrate dev --create-only 실행
    3. 생성된 SQL 파일과 업데이트된 schema.prisma를 현재 PR 브랜치에 커밋 & 푸시
    4. 생성된 파일 경로와 SQL 미리보기를 답글로 게시

5.2.3 마이그레이션 배포 (/deploy)

  • 트리거: PR Comment 명령어 (리뷰 승인 필요)
  • 동작:
    1. Pre-flight Check: prisma migrate status로 미적용 마이그레이션 확인
    2. Backup (Prod): 운영 환경 배포 시 스냅샷 생성 확인
    3. Deploy: prisma migrate deploy 실행하여 실제 DB 스키마 변경
    4. Post-process:
      • Slack 알림 전송 (성공/실패 여부)

5.3 Workflow 구성 예시

5.3.1 마이그레이션 생성 (.github/workflows/migration-generator.yml)

name: Generate Migration
on:
issue_comment:
types: [created]

jobs:
generate:
if: github.event.issue.pull_request && startsWith(github.event.comment.body, '/create-migration')
runs-on: ubuntu-latest
steps:
# (생략: Checkout, Setup Node, Install Deps)

- name: Generate migration
env:
DATABASE_URL: ${{ secrets.DATABASE_URL }}
run: |
npx prisma migrate dev --name ${{ steps.parse.outputs.name }} --create-only

- name: Commit migration files
run: |
git add libs/core/database/prisma/migrations/
git commit -m "chore: generate migration"
git push

5.3.2 마이그레이션 배포 (.github/workflows/migration-deployer.yml)

name: Deploy Migration
on:
issue_comment:
types: [created]

jobs:
deploy:
if: github.event.issue.pull_request && startsWith(github.event.comment.body, '/deploy')
runs-on: ubuntu-latest
steps:
# (생략: Checkout, Setup Node)

- name: Deploy migration
env:
DATABASE_URL: ${{ secrets.PROD_DATABASE_URL }}
run: |
npx prisma migrate deploy --schema libs/core/database/prisma/schema.prisma

5.4 동시성 제어

여러 PR이 동시에 마이그레이션을 생성하는 것을 방지하기 위한 동시성 제어:

concurrency:
group: migration-generator
cancel-in-progress: false # 순차 처리

6. 개발 데이터 관리 방식 (로컬 DB의 경우)

6.1 Prisma Seeding

모든 환경에서 공통적으로 필요한 데이터는 migration/scripts/sql_files/init/ 경로에 .sql 파일 형태로 관리하며, run-init-db.sh 스크립트를 통해 순차적으로 실행합니다.

  • 실행 방법:
    # 모든 init SQL 파일을 순차적으로 실행
    yarn db:seed
  • 관리 대상: jwk, operation role, plan, agreement, message template 등 애플리케이션의 핵심 정적 데이터.

6.2 Dev DB Dump (테스트 데이터)

실제 서비스와 유사한 복잡한 데이터가 필요한 경우 개발 서버 DB를 덤프하여 사용합니다.

  • 방식: 개인정보가 마킹/정제된(Sanitized) 최신 덤프 파일을 다운로드하여 로컬 DB에 복구합니다.
  • 실행 예시:
    # 로컬 DB 초기화 및 덤프 데이터 복구
    ./scripts/db-sync-dev.sh

7. 배포 상태 및 추적 관리

7.1 Application CI 파이프라인 검증

파일 기반 관리의 단점을 해결하기 위해, 배포 파이프라인 상에서 실제 DB와 소스 코드의 상태를 실시간으로 비교하여 배포를 결정하는 방식

7.1.1 동작 원리

App CI 파이프라인에서 prisma migrate status 명령어를 실행하여, 현재 배포하려는 소스 코드의 마이그레이션 파일들이 대상 DB에 모두 적용되어 있는지 확인합니다.

  1. App CI Job:
    • Step 1: 소스 코드의 migrations/ 폴더와 대상 DB를 연결하여 상태 확인
    • Step 2: 미적용 마이그레이션이 있으면(또는 DB 배포 실패 시) 배포 파이프라인 즉시 중단
    • Step 3: 검증 통과 시에만 Docker 빌드 및 워크플로우 진행

7.1.2 적용 예시 (GitHub Actions)

.github/workflows/deployment-ci-asia-branch.yml 등의 워크플로우 파일에서 App 빌드 전 단계에 추가합니다.

주의: prisma migrate status 명령어 사용 시 --schema 옵션으로 정확한 스키마 파일 경로를 지정해야 합니다.

jobs:
build:
steps:
# ... (Checkout 및 Setup 단계)

- name: Check DB Migration Status (Pre-flight Check)
env:
# 대상 환경의 DB 접속 정보 (release 브랜치따라 결정)
DATABASE_URL: ${{ secrets.PROD_DATABASE_URL }}
run: |
echo "🔍 Checking DB migration status..."

# libs/core/database 경로로 이동하거나 --schema 옵션 사용
# --exit-code: 미적용 마이그레이션이 있을 경우 에러 코드(1)를 반환하여 파이프라인 중단
npx prisma migrate status --schema libs/core/database/prisma/schema.prisma --exit-code

echo "✅ DB migration check passed!"

- name: Build and Push to GCP
# 위 단계가 성공해야만 실행됨
# ...

7.1.3 장점

  • 관리 포인트 최소화: 별도의 JSON 파일을 관리하거나 커밋할 필요가 없습니다.
  • 안전한 배포: DB 마이그레이션이 선행되지 않은 상태에서 App이 배포되는 것을 원천적으로 차단합니다.

7.1.4 단점 및 한계

  • DB 접근 권한: 배포 파이프라인에서 prisma cli 를 통해 DB 에 접근할 수 있어야 하므로 권한 관리가 필요합니다.
  • App 서버에 문제가 없는 DB 마이그레이션의 경우 불필요한 과정이 됩니다.

8. 트러블슈팅 및 복구

8.1 마이그레이션 실패 시 Slack 알림 메시지

배포 스크립트가 마이그레이션 실패를 감지하면 다음과 같은 형식의 Slack 알림을 전송합니다:

🚨 [CRITICAL] DB Schema Migration Failed! 🚨

환경: [Prod/Stage/Dev]
실패 시간: [YYYY-MM-DD HH:MM:SS KST]
배포 브랜치: [release/v1.2.0]
실행된 마이그레이션 파일: [20240105_add_user_profile_table]

상세 에러 로그:

8.2 DB 상태 진단 명령어

마이그레이션 실패 시 현재 DB 상태를 확인하기 위한 Prisma CLI 명령어입니다.

8.2.1 마이그레이션 상태 확인

-- DATABASE_URL = 마이그레이션 실패한 DB 인스턴스 URL
cd libs/core/database
npx prisma migrate status --schema prisma/schema.prisma

출력 예시:

Database schema is up to date!

1 migration found in prisma/migrations

Following migration have not yet been applied:
20240105_add_user_profile_table

To apply pending migration(s), run prisma migrate deploy.

8.2.2 현재 DB 스키마 추출 및 비교

# 현재 DB 상태를 schema.prisma 형식으로 추출
npx prisma db pull --schema prisma/schema.prisma --print > current_db_schema.prisma

# Git에 커밋된 schema.prisma와 비교
diff prisma/schema.prisma current_db_schema.prisma

8.2.3 _prisma_migrations 테이블 직접 조회

-- PostgreSQL 직접 접속 후 실행
SELECT
id,
checksum,
finished_at,
migration_name,
logs,
rolled_back_at,
started_at,
applied_steps_count
FROM _prisma_migrations
ORDER BY started_at DESC
LIMIT 10;

주의: 실패한 마이그레이션이 있을 경우 finished_at이 NULL이거나 logs에 에러 메시지가 기록됩니다.

8.3 복구 절차

8.3.1 prisma migrate resolve 명령어

마이그레이션 이력 테이블(_prisma_migrations)의 상태를 수동으로 보정할 때 사용합니다. 실제 DB 스키마는 변경하지 않고 이력만 수정합니다.

사용 시나리오:

  • 마이그레이션 SQL은 성공했으나 Prisma 이력 기록에 실패한 경우
  • 수동으로 스키마를 수정한 후 이력을 동기화해야 하는 경우

명령어 예시:

# 실패로 표시된 마이그레이션을 "적용됨"으로 표시
npx prisma migrate resolve --applied "20240105_add_user_profile_table"

# 특정 마이그레이션을 "롤백됨"으로 표시
npx prisma migrate resolve --rolled-back "20240105_add_user_profile_table"

⚠️ 경고: 이 명령어는 이력만 수정하므로, 실제 DB 스키마와 일치하는지 반드시 prisma migrate statusdb pull로 확인해야 합니다.

8.3.2 백업본 복구

운영 환경에서 마이그레이션 실패 시 가장 안전한 방법은 배포 전 백업본으로 완전히 복구하는 것입니다.

절차:

  1. 서비스 중단
  2. 백업본(Snapshot) 복구
  3. 복구 완료 후 prisma migrate status 확인
  4. 마이그레이션 원인 분석 및 수정 후 재배포

8.3.3 Hotfix 마이그레이션 작성

실패 원인이 명확하고 단순한 SQL 오류인 경우, 수정된 마이그레이션 파일을 새로 생성하여 재배포합니다.

절차:

  1. 로컬에서 원인 수정 후 새 마이그레이션 생성:

    npx prisma migrate dev --name hotfix_${original_migration_name} --create-only
  2. SQL 파일 검토 후 긴급 PR 생성

  3. 승인 후 즉시 배포

8.4 일반적인 문제 해결 (prisma error)

문제 상황원인해결 방법
Migration already applied이력 테이블과 실제 상태 불일치prisma migrate resolve --applied로 상태 보정
Migration failed in a transactionSQL 구문 오류 또는 제약 조건 위반SQL 수정 후 Hotfix 마이그레이션 생성
Database schema drift detected수동 스키마 변경 또는 미적용 파일 존재prisma migrate deploy 재실행 또는 db pull로 상태 확인 후 보정

9. FAQ 및 일반적인 시나리오

9.1 마이그레이션 생성 후 스키마를 다시 수정하면?

시나리오: 마이그레이션 생성 후 리뷰 과정에서 스키마 수정 필요

해결 방법:

  1. 스키마 파일 수정 및 커밋
  2. 기존 마이그레이션 파일 삭제
  3. /create-migration <이름> 명령으로 새 마이그레이션 재생성 (새로운 타임스탬프 부여)

또는:

  1. 생성된 migration.sql 파일을 직접 수정
  2. 수정사항 커밋 및 푸시

9.2 로컬에서 마이그레이션을 테스트하고 싶을 때

방법:

# PR 브랜치 최신화
git pull origin feature-branch

# 로컬 DB에 마이그레이션 적용
cd libs/core/database
npx prisma migrate deploy --schema prisma/schema.prisma

9.4 긴급 Hotfix가 필요한 경우

시나리오: Production에서 긴급 스키마 수정 필요

절차:

  1. Hotfix 브랜치 생성 (hotfix/fix-user-table)
  2. 스키마 수정 및 PR 생성
  3. /create-migration hotfix_fix_user_table 실행
  4. 빠른 리뷰 및 승인
  5. /deploy prod 실행
  6. Main/Develop 브랜치로 백포트

변경 이력

버전날짜작성자변경 내용
0.64.02026-01-07pibi@weltcorp.com최초 문서 작성