Supabase.com 클라우드(무료 플랜 포함)에서 PostgreSQL DB를 로컬 PC에서 백업·복원하는 방법입니다.
무료플랜의 경우 DB Backup 및 Restore가 제공되지 않습니다. (유료플랜일경우 프로젝트마다 $10정도 비용이 추가됨)
관련 글
- 이 글: Supabase.com 클라우드 서비스 (무료·유료 플랜) —
pg_dump/pg_restore로 원격 DB 접속- Self-hosted Supabase 일일 백업: 직접 서버에 설치한 Supabase — Docker 컨테이너 + Cron 자동화
- Supabase.com → Self-hosted 이전: 클라우드 백업을 Self-hosted로 복원
무료 플랜은 Supabase 대시보드에서 자동 일일 백업을 제공하지 않습니다. 개발·운영 중인 DB를 보호하려면 아래처럼 직접 백업 스크립트를 두는 것이 좋습니다.
개요
| 항목 | 내용 |
|---|---|
| 대상 | Supabase.com 프로젝트 (무료 플랜 포함) |
| 실행 위치 | 로컬 PC 또는 백업용 서버 |
| 필요 도구 | pg_dump, pg_restore (PostgreSQL 클라이언트) |
| 연결 방식 | Session pooler (포트 5432) |
| 백업 형식 | Custom format (pg_dump -F c) |
| 파일명 | {프로젝트별칭}_YYYYMMDD_HHMM.sql |
| 스크립트 | supabase_db_config.sh, supabase_db_backup.sh, supabase_db_restore.sh |
Self-hosted 방식과의 차이
| 구분 | Supabase.com (이 글) | Self-hosted |
|---|---|---|
| DB 위치 | Supabase 클라우드 | 내 서버 Docker |
| 접속 | Pooler 호스트 + DB 비밀번호 | docker exec supabase-db |
| 백업 도구 | pg_dump / pg_restore |
docker exec ... pg_dump |
| 파일 형식 | Custom format (-F c) |
Plain SQL + gzip |
| 자동화 | 수동 실행 (Cron 추가 가능) | Cron 일일 자동 백업 |
| 설정 | 프로젝트별 연결 정보 파일 | 서버 경로·보관 일수 |
사전 준비
1. PostgreSQL 클라이언트 설치
로컬 PC에 pg_dump, pg_restore가 있어야 합니다.
# macOS (Homebrew)
brew install libpq
brew link --force libpq
# Ubuntu / Debian
sudo apt install postgresql-client
# 버전 확인
pg_dump --version
pg_restore --version
2. Supabase 대시보드에서 연결 정보 확인
- Supabase Dashboard → 프로젝트 선택
- Project Settings → Database
- Connection string → Session pooler 탭 선택
아래 항목을 메모합니다.
| 항목 | 대시보드 위치 | 예시 |
|---|---|---|
| Host | Session pooler URI | aws-0-ap-northeast-2.pooler.supabase.com |
| Port | Session pooler | 5432 |
| Database | URI | postgres |
| User | URI | postgres.abcdefghijklmnop |
| Password | Database password | (직접 설정·확인) |
Session pooler를 쓰는 이유
pg_dump/pg_restore는 Session mode pooler(포트5432)에서 동작합니다.- Transaction pooler(포트
6543)는 백업·복원에 적합하지 않습니다.- Direct connection도 가능하지만, IPv4 추가 옵션·방화벽 설정이 필요할 수 있습니다.
3. 스크립트 파일 준비
작업 폴더에 아래 3개 파일을 둡니다.
supabase-backup/
├── supabase_db_config.sh # 프로젝트별 DB 연결 정보
├── supabase_db_backup.sh # 백업
└── supabase_db_restore.sh # 복원
chmod +x supabase_db_backup.sh supabase_db_restore.sh
supabase_db_config.sh
Supabase.com 프로젝트가 2개 이상일 때, 프로젝트마다 Host·User·비밀번호가 다릅니다.
매번 긴 연결 문자열을 입력하지 않도록, 별칭(-prj 인자) 과 DB 정보를 이 파일에 모아 둡니다.
| 별칭 예 | 용도 |
|---|---|
example.com |
운영(production) |
example.com-staging |
스테이징 |
my-side-project |
다른 Supabase 무료 프로젝트 |
백업·복원 스크립트는 -prj 별칭만 넘기면 get_db_config가 해당 프로젝트 연결 정보를 불러옵니다.
스크립트는 한 벌, 관리할 DB는 case 블록에 추가하는 방식입니다.
# supabase_db_config.sh
# 프로젝트별 연결 정보 공용 설정 파일
# case 블록에 항목을 추가하면 DB를 계속 늘릴 수 있습니다.
get_db_config() {
local PROJECT=$1
case $PROJECT in
"example.com")
DB_HOST="aws-0-ap-northeast-2.pooler.supabase.com"
DB_PORT="5432" # Session pooler
DB_DATABASE="postgres"
DB_USER="postgres.abcdefghijklmnop"
DB_PASS="YOUR_DATABASE_PASSWORD"
DB_POOLMODE="session"
;;
"example.com-staging")
DB_HOST="aws-0-ap-northeast-1.pooler.supabase.com"
DB_PORT="5432"
DB_DATABASE="postgres"
DB_USER="postgres.stuvwxyzabcdefghij"
DB_PASS="YOUR_STAGING_PASSWORD"
DB_POOLMODE="session"
;;
*)
echo "Unknown project: $PROJECT"
return 1
;;
esac
return 0
}
여러 DB 백업·복원 예
등록된 별칭마다 같은 명령으로 실행합니다. 백업 파일명에도 별칭이 들어가 구분됩니다.
# 운영 백업 → example.com_20260207_0238.sql
./supabase_db_backup.sh -prj example.com
# 스테이징 백업 → example.com-staging_20260207_0303.sql
./supabase_db_backup.sh -prj example.com-staging
# 운영 백업을 스테이징에 복원
./supabase_db_restore.sh -prj example.com-staging -file example.com_20260207_0238.sql
보안:
DB_PASS는 Git에 올리지 마세요..gitignore에supabase_db_config.sh를 추가하거나, 환경 변수로 분리하는 것을 권장합니다.
supabase_db_backup.sh
#!/bin/bash
# supabase_db_backup.sh
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
source "$SCRIPT_DIR/supabase_db_config.sh"
PROJECT=""
BACKUP_FILE=""
while [[ $# -gt 0 ]]; do
case $1 in
-prj)
PROJECT="$2"
shift 2
;;
-file)
BACKUP_FILE="$2"
shift 2
;;
*)
echo "Unknown option: $1"
echo "Usage: ./supabase_db_backup.sh -prj <project_name> [-file <backup_file>]"
exit 1
;;
esac
done
if [ -z "$PROJECT" ]; then
echo "Usage: ./supabase_db_backup.sh -prj <project_name> [-file <backup_file>]"
exit 1
fi
get_db_config "$PROJECT" || exit 1
if [ -z "$BACKUP_FILE" ]; then
BACKUP_FILE="${PROJECT}_$(date +%Y%m%d_%H%M).sql"
fi
echo "Backing up project: $PROJECT"
echo "Backup file: $BACKUP_FILE"
echo ""
export PGPASSWORD="$DB_PASS"
pg_dump -h "$DB_HOST" \
-p "$DB_PORT" \
-U "$DB_USER" \
-d "$DB_DATABASE" \
-F c \
-f "$BACKUP_FILE"
RESULT=$?
unset PGPASSWORD
if [ $RESULT -eq 0 ]; then
FILE_SIZE=$(ls -lh "$BACKUP_FILE" | awk '{print $5}')
echo "✓ Backup completed: $BACKUP_FILE ($FILE_SIZE)"
else
echo "✗ Backup failed"
exit 1
fi
pg_dump 옵션
| 옵션 | 설명 |
|---|---|
-F c |
Custom format — pg_restore로 복원 가능, 압축·선택 복원에 유리 |
-f |
출력 파일 경로 |
확장자는 .sql이지만 실제로는 바이너리 Custom format 파일입니다. 혼동을 피하려면 .dump 확장자를 써도 됩니다.
supabase_db_restore.sh
#!/bin/bash
# supabase_db_restore.sh
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
source "$SCRIPT_DIR/supabase_db_config.sh"
PROJECT=""
BACKUP_FILE=""
while [[ $# -gt 0 ]]; do
case $1 in
-prj)
PROJECT="$2"
shift 2
;;
-file)
BACKUP_FILE="$2"
shift 2
;;
*)
echo "Unknown option: $1"
echo "Usage: ./supabase_db_restore.sh -prj <project_name> -file <backup_file>"
exit 1
;;
esac
done
if [ -z "$PROJECT" ] || [ -z "$BACKUP_FILE" ]; then
echo "Usage: ./supabase_db_restore.sh -prj <project_name> -file <backup_file>"
exit 1
fi
if [ ! -f "$BACKUP_FILE" ]; then
echo "Error: Backup file '$BACKUP_FILE' not found"
exit 1
fi
get_db_config "$PROJECT" || exit 1
echo "================================"
echo "Restore Information"
echo "================================"
echo "Target Project: $PROJECT"
echo "Database Host: $DB_HOST"
echo "Database Name: $DB_DATABASE"
echo "Backup File: $BACKUP_FILE"
echo "File Size: $(ls -lh "$BACKUP_FILE" | awk '{print $5}')"
echo "================================"
echo ""
echo "WARNING: This will overwrite the existing database!"
echo ""
read -p "Do you want to proceed? (yes/no): " CONFIRM
if [ "$CONFIRM" != "yes" ]; then
echo "Restore cancelled"
exit 0
fi
echo ""
echo "Starting restore..."
echo ""
export PGPASSWORD="$DB_PASS"
pg_restore -h "$DB_HOST" \
-p "$DB_PORT" \
-U "$DB_USER" \
-d "$DB_DATABASE" \
--clean \
-F c \
-v \
"$BACKUP_FILE"
RESULT=$?
unset PGPASSWORD
echo ""
if [ $RESULT -eq 0 ]; then
echo "✓ Restore completed successfully"
else
echo "✗ Restore failed (일부 WARNING은 무시될 수 있음 — 아래 '복원 시 자주 보는 메시지' 참고)"
exit 1
fi
--clean: 복원 전 기존 객체를 삭제합니다. 대상 DB의 데이터가 덮어씌워집니다.
사용 방법
백업
# 프로젝트 별칭으로 백업 (파일명 자동 생성)
./supabase_db_backup.sh -prj example.com
# 파일명 직접 지정
./supabase_db_backup.sh -prj example.com -file my-backup.dump
생성 예:
example.com_20260207_0238.sql
example.com_20260207_0303.sql
복원
./supabase_db_restore.sh -prj example.com-staging -file example.com_20260207_0238.sql
확인 프롬프트에 yes를 입력해야 실행됩니다.
프로젝트 간 이전 (A → B)
운영 DB 백업을 스테이징·새 프로젝트로 옮길 때:
# 1) 운영(production) 백업
./supabase_db_backup.sh -prj example.com
# 2) 스테이징(staging)에 복원
./supabase_db_restore.sh -prj example.com-staging -file example.com_20260207_0238.sql
스크립트 복사해서 사용하기
1. 바꿔야 할 항목 (supabase_db_config.sh)
| # | 항목 | 설명 |
|---|---|---|
| 1 | case 프로젝트 별칭 |
-prj로 쓸 이름 (예: example.com, my-app-dev) |
| 2 | DB_HOST |
Supabase Dashboard → Session pooler Host |
| 3 | DB_PORT |
Session pooler → 5432 |
| 4 | DB_USER |
postgres.{project-ref} 형식 |
| 5 | DB_PASS |
Database password |
| 6 | DB_DATABASE |
보통 postgres (변경 없음) |
DB를 2개 이상 등록하기
supabase_db_config.sh는 여러 Supabase 프로젝트를 한 파일에서 관리하기 위한 설정입니다.
운영·스테이징·사이드 프로젝트처럼 DB가 여러 개면, case 블록에 항목을 하나씩 추가하면 됩니다.
get_db_config() {
local PROJECT=$1
case $PROJECT in
"example.com") # ① 운영
DB_HOST="aws-0-ap-northeast-2.pooler.supabase.com"
DB_PORT="5432"
DB_DATABASE="postgres"
DB_USER="postgres.abcdefghijklmnop"
DB_PASS="YOUR_PRODUCTION_PASSWORD"
DB_POOLMODE="session"
;;
"example.com-staging") # ② 스테이징
DB_HOST="aws-0-ap-northeast-1.pooler.supabase.com"
DB_PORT="5432"
DB_DATABASE="postgres"
DB_USER="postgres.stuvwxyzabcdefghij"
DB_PASS="YOUR_STAGING_PASSWORD"
DB_POOLMODE="session"
;;
"my-side-project") # ③ 추가 프로젝트 — 이렇게 계속 늘릴 수 있음
DB_HOST="aws-0-ap-southeast-1.pooler.supabase.com"
DB_PORT="5432"
DB_DATABASE="postgres"
DB_USER="postgres.xxxxxxxxxxxxxxxx"
DB_PASS="YOUR_SIDE_PROJECT_PASSWORD"
DB_POOLMODE="session"
;;
*)
echo "Unknown project: $PROJECT"
return 1
;;
esac
return 0
}
등록 후에는 별칭만 바꿔 같은 스크립트로 백업·복원합니다.
./supabase_db_backup.sh -prj example.com
./supabase_db_backup.sh -prj example.com-staging
./supabase_db_backup.sh -prj my-side-project
별칭은 Supabase Dashboard의 프로젝트 이름과 같을 필요는 없습니다.
본인이 기억하기 쉬운 이름(도메인, prod / dev 등)을 쓰면 됩니다.
2. 설치·테스트 순서
# 1) 3개 파일을 같은 폴더에 저장
# 2) 실행 권한
chmod +x supabase_db_backup.sh supabase_db_restore.sh
# 3) 연결 테스트 (백업)
./supabase_db_backup.sh -prj example.com
# 4) 파일 생성 확인
ls -lh example.com_*.sql
# 5) (선택) 복원 테스트 — 빈/테스트 프로젝트에서만
./supabase_db_restore.sh -prj example.com-staging -file example.com_20260207_0238.sql
3. 설치 후 체크리스트
- Session pooler(포트
5432) 정보를 사용했는가 -
DB_USER가postgres.{project-ref}형식인가 - 백업 파일이 0바이트가 아닌가
- 복원은 테스트 프로젝트에서 먼저 검증했는가
-
supabase_db_config.sh가 Git에 커밋되지 않았는가
복원 시 자주 보는 메시지
| 메시지 | 의미 | 조치 |
|---|---|---|
WARNING: ... already exists, skipping |
객체가 이미 있음 | --clean 사용 시 흔함, 대부분 무시 가능 |
ERROR: role "..." does not exist |
Supabase 관리 역할 차이 | 기능 이상 없으면 무시 |
connection failed |
호스트·포트·비밀번호 오류 | Session pooler 정보 재확인 |
Tenant or user not found |
DB_USER 오류 |
postgres.{project-ref} 확인 |
SSL connection required |
SSL 필요 | Supabase pooler는 기본 SSL — 클라이언트 버전 확인 |
복원 후 Supabase Studio에서 테이블·데이터를 확인하세요.
무료 플랜에서 알아 둘 점
| 항목 | 내용 |
|---|---|
| 자동 백업 | 무료 플랜은 Supabase 측 자동 DB 백업 없음 → 직접 백업 필요 |
| 프로젝트 일시정지 | 7일 비활성 시 pause — 정기 백업·접속으로 방지 |
| DB 용량 | 500MB 제한 — 백업 파일도 로컬에 쌓이면 디스크 관리 필요 |
| 연결 수 | pooler 경유 시 무료 플랜 연결 제한 내에서 사용 |
| Auth / Storage | 이 스크립트는 PostgreSQL DB만 백업. Storage 파일·Auth 설정은 별도 |
(선택) Cron으로 주기 백업
로컬 Mac/Linux에서 매일 백업하려면:
# 매일 새벽 3시 — example.com 프로젝트 백업
0 3 * * * cd /path/to/supabase-backup && ./supabase_db_backup.sh -prj example.com >> backup.log 2>&1
백업 파일은 외장 디스크·클라우드 스토리지 등 안전한 곳에 보관하세요.
Self-hosted로 이전하기
Supabase.com 백업 파일을 Self-hosted Supabase에 복원하려면 Supabase.com → Self-hosted 이전 가이드 를 참고하세요.
Custom format(-F c)과 Self-hosted plain SQL 형식이 다르므로, 별도 절차가 필요합니다.
보안 유의사항
supabase_db_config.sh에 DB 비밀번호가 들어갑니다. Git 공개 저장소에 올리지 마세요.- 백업 파일에 전체 DB 데이터가 포함됩니다. USB·클라우드 보관 시 암호화를 권장합니다.
- 복원은
--clean으로 기존 데이터를 삭제합니다. 운영 DB 복원 전 반드시 백업을 먼저 만드세요. - 팀원과 설정 파일을 공유할 때는 비밀번호를 별도 채널로 전달하세요.


주파수 소통방 (0)
로딩 중...