IT 개발 관련/잡다한기술

Hasura GraphQL Engine 서버 이관 정리: 설정 백업, 신규 서버 설정, 복원 절차 (Hasura v2.x)

SeanYoon 2026. 11. 2. 17:23
반응형

2026.11 · Hasura GraphQL Engine v2.x 이관 가이드

Hasura 서버 이관: 설정 백업, 신규 서버 구성, 복원 절차 정리

지난 글의 Keycloak 서버 이관에 이어, Keycloak 토큰으로 권한을 처리하는 경우가 많은 Hasura GraphQL Engine(v2) 이관 절차를 정리했습니다. Hasura는 서버 자체에 상태가 거의 없고, 설정(메타데이터)은 DB의 hdb_catalog 스키마에, 비밀값은 환경변수에 들어 있습니다. 이 두 가지를 정확히 옮기는 것이 이관의 전부라고 봐도 됩니다. 2026년 10월 27일 기준 최신 릴리스는 v2.51.3입니다.

핵심 원칙 4가지

1. 메타데이터 + 환경변수 + DB 스키마, 세 가지를 함께 백업해야 복원됩니다. 메타데이터는 환경변수 이름만 참조하는 경우가 많아 값이 없으면 "inconsistent metadata"가 됩니다.
2. 같은 버전 이미지로 옮기고, 업그레이드는 안정화 후 따로 합니다.
3. 구·신 Hasura를 같은 DB에 동시에 붙이지 마세요. 이벤트 트리거, 크론 트리거, 비동기 액션이 두 번 실행될 수 있습니다.
4. 복원 후 메타데이터 일관성 검사를 통과해야 끝난 것입니다.

1. Hasura의 상태는 어디에 저장되나

구성 요소저장 위치백업 방법
메타데이터
(테이블 추적, 관계, 권한, 액션, 리모트 스키마, 이벤트·크론 트리거, Allow list, REST 엔드포인트 등)
메타데이터 DB의 hdb_catalog.hdb_metadata (JSON 한 덩어리)hasura metadata export 또는 Metadata API export_metadata
이벤트·스케줄 기록
(처리 대기 이벤트, 호출 로그, 크론·예약 이벤트, 비동기 액션 로그)
hdb_catalog의 이벤트 관련 테이블DB 덤프로만 옮겨짐(메타데이터 export에는 없음)
DB 스키마
(테이블, 뷰, 함수, 트리거)
데이터 소스 DBhasura migrate 또는 pg_dump
서버 설정·비밀값
(관리자 시크릿, JWT 설정, DB URL, 웹훅 URL)
컨테이너 환경변수 / K8s Secret / .env배포 파일·시크릿 저장소에서 별도 정리

※ HASURA_GRAPHQL_METADATA_DATABASE_URL을 따로 지정하지 않았다면 메타데이터는 기본 데이터 DB(HASURA_GRAPHQL_DATABASE_URL) 안의 hdb_catalog 스키마에 같이 들어 있습니다.

2. 이관 유형과 방식 선택

상황권장 방식
A. Hasura 서버만 이동 (DB는 그대로)같은 버전 이미지 + 같은 환경변수로 새 서버 기동 → 구 서버 중지 → 트래픽 전환. 메타데이터는 DB에 있으므로 따로 복원할 필요 없음
B. Hasura + DB 함께 이동 (같은 DB 엔진)pg_dump로 데이터와 hdb_catalog를 통째로 옮기기(가장 간단하고 이벤트 기록도 보존). CLI 메타데이터 export는 보조 백업으로
C. 새 환경을 처음부터 구성 (스키마만 옮기고 데이터는 별도, 또는 환경 정리)Hasura CLI 프로젝트(migrations + metadata)로 재구성: migrate apply → metadata apply

3. 설정 백업

① 현재 버전과 상태 확인

export HASURA_ENDPOINT=https://graphql.example.com
export HASURA_ADMIN_SECRET='********'

# 서버 버전 (새 서버도 같은 태그로 맞출 것)
curl -s $HASURA_ENDPOINT/v1/version

# 헬스체크
curl -s -o /dev/null -w "%{http_code}\n" $HASURA_ENDPOINT/healthz

② 메타데이터 백업 (CLI 프로젝트 방식, 권장)

# CLI 설치 후 프로젝트 초기화 (config v3)
hasura init hasura-backup --endpoint $HASURA_ENDPOINT --admin-secret $HASURA_ADMIN_SECRET
cd hasura-backup

# 메타데이터 내보내기 (YAML 파일로 metadata/ 아래 저장)
hasura metadata export

# 이관 전 일관성 상태도 기록 (이미 inconsistent한 항목이 있는지)
hasura metadata inconsistency list

# 변경 이력 관리
git init && git add . && git commit -m "metadata snapshot before migration"

③ JSON 한 파일로도 백업 (API 방식, CLI 없이 가능)

curl -s -X POST $HASURA_ENDPOINT/v1/metadata \
  -H "X-Hasura-Admin-Secret: $HASURA_ADMIN_SECRET" \
  -H "Content-Type: application/json" \
  -d '{"type":"export_metadata","version":2,"args":{}}' \
  | jq '.metadata' > metadata-$(date +%Y%m%d).json

④ DB 스키마 백업 (마이그레이션 파일 생성)

# 이미 마이그레이션 이력이 없다면, 현재 스키마로 초기 마이그레이션 생성
hasura migrate create "init" --from-server --database-name default

# 적용 상태 확인
hasura migrate status --database-name default

⑤ 환경변수 목록 정리 (값은 시크릿 저장소에서 관리, 파일로 평문 저장 금지)

# 실행 중인 컨테이너의 Hasura 관련 환경변수 이름 확인
docker inspect hasura --format '{{range .Config.Env}}{{println .}}{{end}}' | grep -E '^HASURA_|_URL=' | cut -d= -f1

# 메타데이터가 참조하는 환경변수 이름 찾기 (from_env, {{ENV_NAME}} 템플릿)
grep -rhoE 'from_env: *[A-Z0-9_]+|\{\{[A-Z0-9_]+\}\}' metadata/ | sort -u

⑥ DB 전체 백업 (유형 B)

# Hasura를 먼저 중지해 이벤트 처리를 멈춘 뒤 덤프 (hdb_catalog 포함)
pg_dump -Fc -h old-db -U postgres -d appdb -f appdb-$(date +%Y%m%d%H%M).dump

# 메타데이터 DB를 분리해 쓰고 있다면 그것도 따로
pg_dump -Fc -h old-db -U postgres -d hasura_metadata -f hasura-metadata.dump

4. 신규 서버 설정

구 서버와 같은 버전 태그의 이미지를 쓰고, 정리해 둔 환경변수를 모두 넣습니다. 아래는 Docker Compose 예시입니다.

# docker-compose.yml (예시)
services:
  hasura:
    image: hasura/graphql-engine:v2.51.3      # 구 서버와 동일한 태그로 고정
    restart: always
    ports:
      - "8080:8080"
    environment:
      # 메타데이터 DB (hdb_catalog 위치)
      HASURA_GRAPHQL_METADATA_DATABASE_URL: ${HASURA_METADATA_DB_URL}
      # 메타데이터의 databases.yaml에서 from_env로 참조하는 데이터 소스 URL
      PG_DATABASE_URL: ${PG_DATABASE_URL}

      HASURA_GRAPHQL_ADMIN_SECRET: ${HASURA_ADMIN_SECRET}
      # Keycloak 등 외부 IdP 토큰 검증 (issuer가 바뀌면 여기도 수정)
      HASURA_GRAPHQL_JWT_SECRET: '{"jwk_url":"https://auth.example.com/realms/myrealm/protocol/openid-connect/certs","issuer":"https://auth.example.com/realms/myrealm"}'
      HASURA_GRAPHQL_UNAUTHORIZED_ROLE: anonymous

      # 액션·이벤트 트리거·리모트 스키마가 참조하는 URL (메타데이터의 {{...}} 템플릿)
      ACTION_BASE_URL: ${ACTION_BASE_URL}

      # 운영 권장값
      HASURA_GRAPHQL_ENABLE_CONSOLE: "false"
      HASURA_GRAPHQL_DEV_MODE: "false"
      HASURA_GRAPHQL_ENABLED_APIS: "graphql,metadata"
      HASURA_GRAPHQL_CORS_DOMAIN: "https://app.example.com"
  • 네트워크: 새 서버에서 DB, 액션 핸들러, 이벤트 웹훅, 리모트 스키마 서버, JWK URL(Keycloak)로 나가는 연결이 열려 있어야 합니다. 상대 쪽 IP 허용 목록에도 새 서버 IP를 등록하세요.
  • DB 권한: 메타데이터 DB 계정은 hdb_catalog 스키마 생성·수정 권한이 필요하고, 데이터 소스 계정은 이벤트 트리거를 쓰면 트리거·함수 생성 권한이 필요합니다.
  • 메타데이터 API 노출: 운영에서는 콘솔을 끄고, 관리 API(/v1/metadata)는 내부망이나 관리자 시크릿으로만 접근하게 하세요.

5. 복원 과정

유형 B: DB 덤프 복원 (권장)

# 1) 구 Hasura 중지 (이벤트·크론 중복 실행 방지)
docker compose -f old/docker-compose.yml stop hasura

# 2) 새 DB에 복원 (hdb_catalog 스키마와 이벤트 트리거용 DB 트리거·함수 포함)
createdb -h new-db -U postgres appdb
pg_restore -h new-db -U postgres -d appdb --no-owner appdb-*.dump

# 3) 새 Hasura 기동 → 메타데이터는 DB에서 그대로 읽힘
docker compose up -d hasura

유형 C: CLI로 스키마 → 메타데이터 순서로 적용

cd hasura-backup
export NEW=https://graphql-new.internal.example.com

# 1) 데이터 소스 연결 정보만 먼저 적용 (최근 CLI에 추가된 명령, config v3. 없는 버전이면 생략)
hasura metadata apply-data-sources --endpoint $NEW --admin-secret $HASURA_ADMIN_SECRET

# 2) DB 스키마 마이그레이션 적용 (테이블·함수가 먼저 있어야 메타데이터가 붙음)
hasura migrate apply --all-databases --endpoint $NEW --admin-secret $HASURA_ADMIN_SECRET

# 3) 메타데이터 적용 (불일치가 있으면 적용 거부)
hasura metadata apply --disallow-inconsistent-metadata --endpoint $NEW --admin-secret $HASURA_ADMIN_SECRET

# 4) 다시 읽고 일관성 확인
hasura metadata reload --endpoint $NEW --admin-secret $HASURA_ADMIN_SECRET
hasura metadata inconsistency list --endpoint $NEW --admin-secret $HASURA_ADMIN_SECRET

# 5) 구 서버와 차이 비교 (출력이 없으면 동일)
hasura metadata diff --endpoint $NEW --admin-secret $HASURA_ADMIN_SECRET

※ metadata apply는 기존 메타데이터를 통째로 교체합니다. 부분 적용은 없으므로 대상 서버를 꼭 확인하세요. 컨테이너 기동 시 자동 적용하려면 hasura/graphql-engine:<버전>.cli-migrations-v3 이미지에 /hasura-migrations, /hasura-metadata를 마운트하는 방법도 있습니다.

API로 JSON 복원 (CLI 없이)

jq '{type:"replace_metadata", version:2, args:{metadata: ., allow_inconsistent_metadata:false}}' metadata-20261102.json \
  | curl -s -X POST $NEW/v1/metadata \
      -H "X-Hasura-Admin-Secret: $HASURA_ADMIN_SECRET" -H "Content-Type: application/json" -d @-

6. 검증 체크리스트

# 메타데이터가 일관적이지 않으면 실패를 반환하는 엄격 헬스체크
curl -s -o /dev/null -w "%{http_code}\n" "$NEW/healthz?strict=true"

# Keycloak 토큰으로 실제 권한 확인 (role별로 반복)
curl -s $NEW/v1/graphql -H "Authorization: Bearer $USER_TOKEN" \
  -d '{"query":"{ __typename }"}'
영역확인 항목
일관성inconsistency list 비어 있음, metadata diff 차이 없음, 엄격 헬스체크 200
인증·권한JWT 검증(issuer·JWK), 역할별 select/insert/update 권한, 익명 역할, 관리자 시크릿
쿼리주요 쿼리·뮤테이션·구독(WebSocket), REST 엔드포인트, Allow list
액션·리모트 스키마핸들러 URL 응답, 전달 헤더, 리모트 스키마 로딩
이벤트·크론테스트 행 변경 시 이벤트 1회만 전달, 크론 트리거 다음 실행 시각, 대기 이벤트 처리
운영로그 수집, 메트릭, 응답시간, 커넥션 풀, CORS

7. 자주 막히는 지점

  • Inconsistent metadata: 대부분 환경변수 누락(데이터 소스 URL, 액션 URL), 새 DB에 테이블이 없음, 리모트 스키마 서버에 접속 불가 때문입니다. inconsistency list에 원인이 나옵니다.
  • 이벤트 중복 전달: 구·신 Hasura가 같은 DB를 보고 있으면 둘 다 이벤트를 가져가 처리합니다. 웹훅 쪽은 멱등하게 만들어 두는 것이 좋습니다.
  • JWT 검증 실패: Keycloak 이관으로 issuer나 키가 바뀌었다면 HASURA_GRAPHQL_JWT_SECRET의 issuer, jwk_url도 바꿔야 합니다.
  • 설명(description)이 사라짐: v2.50.4 / v2.51.1부터 PostgreSQL의 COMMENT를 GraphQL 설명으로 가져오지 않습니다(breaking change). 이 버전 이상으로 옮기거나 올린다면 hasura metadata codemod migrate-postgres-comments로 주석을 메타데이터에 옮긴 뒤 적용하세요.
  • 이벤트 트리거 이름 검증: v2.50.0부터 이름에 영문·숫자·밑줄·하이픈만 허용합니다. 예전 이름이 규칙에 맞지 않으면 다음 replace_metadata(=metadata apply) 전에 고쳐야 합니다.

8. 롤백과 버전 업그레이드

  • 롤백: 구 서버를 지우지 않고 중지 상태로 둡니다. 유형 A·B는 트래픽만 되돌리면 되고, 유형 C는 Git에 커밋한 메타데이터 스냅샷을 다시 apply하면 됩니다. 메타데이터는 스냅샷 단위라 "특정 시점 통째로 되돌리기"만 가능합니다.
  • 업그레이드: Hasura는 기동 시 hdb_catalog 버전을 자동으로 올립니다. 이관이 끝나고 안정화된 뒤, 스테이징에서 릴리스 노트의 breaking change를 확인하고 진행하세요. 업그레이드 직전 DB 백업이 곧 롤백 수단입니다.

9. 일정별 요약

시점할 일
D-7버전·환경변수·외부 연동(액션, 웹훅, 리모트 스키마, JWK) 목록화, 메타데이터 export와 Git 커밋, 새 서버 네트워크 개방 요청
D-3스테이징에서 복원 리허설, 일관성 검사·권한 테스트 스크립트 준비
D-day메타데이터 변경 동결 → 구 Hasura 중지 → DB 백업·복원(또는 migrate/metadata apply) → 새 Hasura 기동 → 엄격 헬스체크 → 트래픽 전환 → 검증
D+1 ~ D+7이벤트 실패·재시도 로그, 응답시간 모니터링, 안정화 후 구 서버 폐기

참고 자료

· Hasura Docs v2: Manage Metadata, hasura metadata export / apply, hasura migrate apply, Metadata API(export_metadata, replace_metadata)
· Hasura Docs: Updating to Hasura GraphQL Engine v2 (HASURA_GRAPHQL_METADATA_DATABASE_URL)
· GitHub hasura/graphql-engine Releases (v2.50.0 ~ v2.51.3, 2026.08~10)
· 이전 글: Keycloak 서버 이관 작업 정리

※ 명령어와 설정은 예시이므로 환경(배포 방식, DB 구성, CLI config 버전)에 맞게 조정하고 반드시 스테이징에서 먼저 검증하세요.

반응형