
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 스키마 (테이블, 뷰, 함수, 트리거) | 데이터 소스 DB | hasura 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 버전)에 맞게 조정하고 반드시 스테이징에서 먼저 검증하세요.