코어 데이터베이스 마이그레이션 관리

이 페이지

EmDash 코어 마이그레이션은 EmDash 자체의 테이블과 콘텐츠 테이블의 표준 컬럼을 업데이트합니다. 컬렉션과 필드를 생성, 제거 또는 이름 변경하지 않습니다. 콘텐츠 모델 변경에 대해서는 Evolving a Deployed Site를 참조하세요.

런타임 마이그레이션 모드는 기본적으로 auto이므로 기존 배포는 시작 시 보류 중인 코어 마이그레이션을 계속 적용합니다. 배포 관리 마이그레이션을 사용하면 새 애플리케이션 코드가 트래픽을 받기 전에 빌드가 데이터베이스를 마이그레이션하고, 런타임이 해당 배포 단계를 검증하거나 신뢰할 수 있습니다.

빌드, 마이그레이션, 배포, 체크

Astro 빌드 또는 동기화는 .emdash/migrations.json을 작성합니다. 이 비밀 정보가 없는 매니페스트는 해당 빌드에서 사용된 정확한 EmDash 버전, 정렬된 마이그레이션 세트, 로케일 구성 및 어댑터 마이그레이션 실행기를 기록합니다.

매니페스트를 생성한 종속성이 있는 프로젝트에서 이 명령을 실행하세요. 먼저 빌드하고 대상을 검사합니다.

pnpm build
pnpm emdash migrate --status

보고된 대상이 의도한 데이터베이스인지 확인한 후 대화형 마이그레이션을 시작합니다. 확인하기 전에 프롬프트에서 대상을 다시 검토하세요. 그런 다음 같은 빌드를 배포하고 배포된 스키마를 확인합니다.

pnpm emdash migrate
pnpm wrangler deploy
pnpm emdash migrate --check

emdash migrate --status는 데이터베이스를 변경하지 않고 적용됨, 보류 중, 알 수 없는 마이그레이션을 보고합니다. 일반 emdash migrate 명령은 대상을 표시하고 보류 중인 마이그레이션을 적용하기 전에 확인을 요청합니다.

--check는 마이그레이션을 적용하지 않으며, 알려진 마이그레이션이 보류 중이거나 데이터베이스에 빌드에 알려지지 않은 마이그레이션 레코드가 포함된 경우 0이 아닌 코드로 종료합니다. check의 “작업 필요” 0이 아닌 종료 상태 없이 동일한 마이그레이션 세트를 검사하려면 --status를 사용하세요. CLI 레퍼런스는 보류, 알 수 없음, 확인, 중단 및 운영 종료 코드를 구분합니다.

비대화형 적용과 모든 --json 적용에는 --expected-target-fingerprint가 필요합니다. 확인된 대상이 일치하지 않으면 명령이 실패합니다. 이 옵션은 자동화된 배포 작업에서 사용하고, 위에 설명된 대화형 워크플로에서는 사용하지 마세요.

다른 곳에 저장된 매니페스트에는 --manifest path/to/migrations.json을 사용하세요. 로컬 조사를 위해 --from-config [--config astro.config.mjs]는 Astro 훅을 실행하거나 서버를 시작하지 않고 신뢰할 수 있는 프로젝트 구성을 명시적으로 평가합니다. 배포 파이프라인은 빌드 매니페스트를 사용해야 합니다.

데이터베이스를 명시적으로 선택

구성된 어댑터는 비밀 정보가 없는 대상 정보를 매니페스트에 제공합니다. 자격 증명은 환경 변수에 남아 마이그레이션 명령만 읽습니다.

어댑터매니페스트 대상기본 자격 증명 변수유용한 오버라이드
SQLite데이터베이스 경로 또는 file: URL--database <경로>
libSQL공개 URLTURSO_AUTH_TOKENmigrationAuthTokenEnv 구성
PostgreSQL연결 변수 이름DATABASE_URL--database-url-env <이름>
Cloudflare D1Wrangler 바인딩 이름CLOUDFLARE_API_TOKEN--d1, --account-id, --wrangler-config, --wrangler-env
Hyperdrive기본 바인딩 및 오리진 변수 이름바인딩별 직접 오리진 변수migrationConnectionStringEnv 구성

상대 SQLite 경로는 설치된 EmDash 패키지나 셸의 현재 하위 디렉터리가 아닌 프로젝트 루트에서 확인됩니다. PostgreSQL, libSQL 및 Hyperdrive 대상 레이블은 자격 증명과 URL 매개변수를 생략합니다.

마이그레이션 전에 D1 프로비저닝

D1 데이터베이스 생성과 스키마 마이그레이션은 별도의 작업입니다. emdash migrate는 누락된 데이터베이스를 생성하지 않습니다.

  1. 데이터베이스를 프로비저닝하고 프로덕션 UUID를 기록합니다.

    pnpm wrangler d1 create my-site-production
  2. 해당 UUID를 wrangler.jsonc의 의도한 바인딩과 환경에 추가합니다.

  3. D1 바인딩이 .emdash/migrations.json에 기록되도록 사이트를 빌드합니다.

  4. 계정 ID와 D1 편집 권한이 있는 범위 지정 토큰을 설정합니다. 선택한 대상을 검사한 다음 대화형 마이그레이션을 실행합니다. 계정과 데이터베이스가 의도한 프로덕션 데이터베이스와 일치하는 경우에만 프롬프트를 확인하세요.

    export CLOUDFLARE_ACCOUNT_ID="..."
    export CLOUDFLARE_API_TOKEN="..."
    pnpm emdash migrate \
      --status \
      --wrangler-config wrangler.jsonc \
      --wrangler-env production
    pnpm emdash migrate \
      --wrangler-config wrangler.jsonc \
      --wrangler-env production

대신 --account-id--d1 <데이터베이스-UUID-또는-이름>과 함께 제공할 수 있습니다. 이름 조회는 정확히 하나의 데이터베이스로 확인되어야 합니다. 미리보기 ID, 자리표시자 ID, 충돌하는 계정 및 모호한 바인딩은 닫힌 상태로 실패합니다.

CI에서 D1 마이그레이션 구성

D1은 PostgreSQL이 사용하는 자문 마이그레이션 잠금을 제공하지 않습니다. 계정 및 데이터베이스 UUID당 최대 하나의 마이그레이션 작업을 실행하세요.

CI 환경에서 다음 시크릿과 변수를 설정하세요:

  • 시크릿 CLOUDFLARE_API_TOKEN: D1 편집 권한이 있는 범위 지정 토큰.
  • 변수 CLOUDFLARE_ACCOUNT_ID: 데이터베이스를 소유한 Cloudflare 계정 ID.
  • 변수 D1_DATABASE_ID: 프로덕션 D1 데이터베이스 UUID.
  • 변수 EMDASH_TARGET_FINGERPRINT: 로컬에서 계정과 데이터베이스를 검토한 후 emdash migrate --status가 출력하는 핑거프린트.

다음 GitHub Actions 워크플로는 이 값들을 사용하며 동시성 그룹을 두 불변 D1 식별자에 키잉합니다. 적용 단계는 비대화형이므로 검토된 대상 핑거프린트를 명시적으로 제공합니다.

name: Deploy

on:
  workflow_dispatch:

concurrency:
  group: emdash-migrations-${{ vars.CLOUDFLARE_ACCOUNT_ID }}-${{ vars.D1_DATABASE_ID }}
  cancel-in-progress: false

jobs:
  deploy:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
      - uses: pnpm/action-setup@v4
      - uses: actions/setup-node@v4
        with:
          node-version: 22
          cache: pnpm
      - run: pnpm install --frozen-lockfile
      - run: pnpm build
      - name: Inspect EmDash migration target
        env:
          CLOUDFLARE_API_TOKEN: ${{ secrets.CLOUDFLARE_API_TOKEN }}
        run: |
          pnpm emdash migrate --status --json \
            --account-id "${{ vars.CLOUDFLARE_ACCOUNT_ID }}" \
            --d1 "${{ vars.D1_DATABASE_ID }}"
      - name: Apply EmDash migrations
        env:
          CLOUDFLARE_API_TOKEN: ${{ secrets.CLOUDFLARE_API_TOKEN }}
          EMDASH_TARGET_FINGERPRINT: ${{ vars.EMDASH_TARGET_FINGERPRINT }}
        run: |
          pnpm emdash migrate \
            --account-id "${{ vars.CLOUDFLARE_ACCOUNT_ID }}" \
            --d1 "${{ vars.D1_DATABASE_ID }}" \
            --expected-target-fingerprint "$EMDASH_TARGET_FINGERPRINT"
      - run: pnpm wrangler deploy
      - name: Check EmDash migrations
        env:
          CLOUDFLARE_API_TOKEN: ${{ secrets.CLOUDFLARE_API_TOKEN }}
        run: |
          pnpm emdash migrate --check \
            --account-id "${{ vars.CLOUDFLARE_ACCOUNT_ID }}" \
            --d1 "${{ vars.D1_DATABASE_ID }}"

변경된 대상을 로컬에서 검토한 후에만 EMDASH_TARGET_FINGERPRINT를 업데이트하세요. 핑거프린트에는 자격 증명이 포함되지 않지만, 계정과 데이터베이스를 확인하지 않고 변경하면 잘못된 데이터베이스를 마이그레이션하는 것에 대한 보호가 제거됩니다.

Hyperdrive는 오리진에 연결

Hyperdrive의 마이그레이션 실행기는 오리진에 직접 PostgreSQL 연결을 엽니다. Hyperdrive를 통해 마이그레이션 트래픽을 보내지 않고, 선택적 캐시 바인딩을 사용하지 않으며, Worker의 프라이빗 네트워크 도달성을 상속하지 않습니다.

배포 러너가 오리진에 도달할 수 있어야 합니다. 기본 바인딩별 변수가 적합하지 않은 경우 hyperdrive()migrationConnectionStringEnv를 설정하고, 해당 변수는 마이그레이션 작업에만 제공하세요. 런타임 Hyperdrive 자격 증명과 직접 오리진 배포 자격 증명을 분리하세요.

런타임 적용을 점진적으로 채택

다음 EmDash 통합 구성은 개발 중 자동 마이그레이션을 유지하면서 런타임 적용을 활성화합니다.

emdash({
	database,
	migrations: {
		runtime: "check",
		dev: "auto",
	},
});
  • auto는 하위 호환 기본값입니다. 런타임 시작 시 보류 중인 마이그레이션을 확인하고 적용합니다.
  • check는 방향성 상태 쿼리를 수행하고, 알려진 마이그레이션이 보류 중일 때 요청을 처리하기 전에 503을 반환합니다. 롤링 배포 중 더 새로운 호환 빌드의 레코드를 허용합니다.
  • manual은 런타임 마이그레이션이나 상태 쿼리를 수행하지 않습니다. 배포 파이프라인이 모든 빌드를 안정적으로 적용하고 확인한 후에만 사용하세요.

EMDASH_MIGRATIONS_MODE는 동일한 아티팩트가 여러 환경을 통해 승격될 때 런타임 모드를 오버라이드할 수 있습니다. 설정 및 개발 바이패스 경로는 유효 모드를 따릅니다. checkmanual 뒤에서 자동으로 마이그레이션할 수 없습니다.

보수적인 롤아웃은 배포 작업 도입 중 auto, 작업이 안정적이 된 후 check, 모든 배포에 외부 확인이 적용될 때 manual입니다.

롤링 배포 중 호환성

코어 마이그레이션은 expand/deploy/contract 시퀀싱을 따릅니다. 배포는 확장된 데이터베이스에 대해 일시적으로 이전 및 새 애플리케이션 격리를 실행할 수 있으며, 백필이 아직 진행 중일 수 있습니다. 모든 배포된 버전이 스키마 사용을 중단할 때까지 축소하지 마세요.

알 수 없는 적용된 마이그레이션 레코드는 이 롤링 배포 방향에 대해서만 런타임 check에서 허용됩니다. CLI의 정확한 체크는 이를 보고하고 apply는 변경을 거부합니다. 데이터베이스가 더 새로운 것이거나 분기된 마이그레이션 이력을 가질 수 있기 때문입니다.

문제 해결

  • 마이그레이션 매니페스트를 찾을 수 없습니다. 먼저 프로젝트를 빌드하거나 동기화하세요. 비표준 아티팩트 위치에는 --manifest를, 로컬 조사에는 명시적으로 --from-config를 선택하세요.
  • 아티팩트가 프로젝트의 EmDash와 일치하지 않습니다. 애플리케이션과 매니페스트를 함께 리빌드하고 배포하세요. 글로벌 설치 대신 프로젝트의 CLI를 실행하세요.
  • 대상이 누락되었거나 모호합니다. 먼저 프로비저닝한 다음 명시적 데이터베이스 경로, 연결 변수 이름, D1 선택기 또는 선택한 Wrangler 구성 및 환경을 제공하세요. EmDash는 관련 없는 환경 변수나 바인딩에서 추측하지 않습니다.
  • 대상 핑거프린트가 변경되었습니다. 중지하고 표시된 계정, 환경, 데이터베이스 이름, UUID 또는 경로를 검토하세요. 의도한 대상을 확인한 후에만 예상 핑거프린트를 업데이트하세요.
  • 알 수 없는 마이그레이션 레코드가 있습니다. 레코드를 삭제하거나 apply를 다시 실행하지 마세요. 애플리케이션 아티팩트가 의도한 버전인지 확인하고, 더 새로운 또는 분기된 빌드가 데이터베이스를 마이그레이션했는지 조사하세요.
  • D1 쓰기 결과가 모호합니다. 마이그레이션 명령을 다시 실행하지 마세요. 같은 계정과 데이터베이스 UUID에 대해 emdash migrate --status를 실행하고, 결과를 검사하고, 마이그레이션이 중간에 중단된 경우 에스컬레이션하세요.
  • Hyperdrive가 연결할 수 없습니다. 배포 러너에서 PostgreSQL 오리진까지의 도달성을 테스트하고 직접 오리진 변수를 확인하세요. Worker 대 Hyperdrive 연결은 러너가 오리진에 도달할 수 있음을 증명하지 않습니다.