← 가이드 목록 T-Taxi · 개발자

DB 자동 백업 (pg_dump → R2)

P1 1차 방어. 호스트 cron이 매일 one-shot 컨테이너로 prod DB를 R2에 백업. (원본: infra/backup/)

!현황 — 실가동 중 ✅

2026-06-01 서버 42.127.251.21에 배포·검증 완료. 매일 03:00 KST pg_dump(custom) → age 암호화 → R2 ktaxi-backups/daily/ 업로드 → 최신 14개 보존.
실백업 적재 + 복구 리허설(스크래치 DB 복원, 행수 prod 일치) 통과.
호스트 cron 03:00 one-shot 컨테이너 pg_dump age 암호화 R2 업로드 14개 보존

1설계 결정 (왜?)

R2 인증rclone/S3 키 대신 Cloudflare API 토큰(Bearer) + R2 REST API. 키쌍 발급 불필요
DB 접속운영 pg_hba127.0.0.1 trust + 비번 로테이션됨 → 컨테이너를 --network container:ktaxi-postgres로 postgres netns에 붙여 127.0.0.1 trust 접속(비번 보관 불필요)
스케줄상시 사이드카 대신 호스트 crondocker run --rm 트리거 → 단순·견고
암호화age 공개키로 암호화. 개인키는 서버에 두지 않음(재해 시 복구 위해 오프사이트 보관)
서버 배포

2구성 (1회)

① 이미지 빌드

scp infra/backup/backup.sh infra/backup/Dockerfile root@<server>:/opt/ktaxi/backup/
ssh root@<server> 'cd /opt/ktaxi/backup && docker build -t ktaxi-backup .'

② /opt/ktaxi/backup/backup.env (chmod 600, git 금지)

PGHOST=127.0.0.1
PGPORT=5432
PGUSER=ktaxi
PGDATABASE=ktaxi
R2_ACCOUNT_ID=eafb6baf7a01357c80a79a2aac693f80
R2_API_TOKEN=<Cloudflare R2 Read&Write 토큰>
R2_BUCKET=ktaxi-backups
BACKUP_AGE_RECIPIENT=<백업 age 공개키>
RETENTION_COUNT=14
TZ=Asia/Seoul

③ cron 설치

scp infra/backup/ktaxi-backup.cron root@<server>:/etc/cron.d/ktaxi-backup
ssh root@<server> 'chmod 644 /etc/cron.d/ktaxi-backup; touch /var/log/ktaxi-backup.log'

④ 즉시 1회 실행

docker run --rm --network container:ktaxi-postgres --env-file /opt/ktaxi/backup/backup.env ktaxi-backup

3복구 (restore)

# 1) R2 최신 백업 다운로드
API=https://api.cloudflare.com/client/v4/accounts/$ACCT/r2/buckets/ktaxi-backups/objects
LATEST=$(curl -fsS "$API?prefix=daily/" -H "Authorization: Bearer $TOKEN" | jq -r '.result|sort_by(.key)|last.key')
curl -fsS "$API/$LATEST" -H "Authorization: Bearer $TOKEN" -o /tmp/latest.age

# 2) 복호화 (오프사이트 개인키)
age -d -i <age-key.txt> /tmp/latest.age > /tmp/latest.dump

# 3) 스크래치 DB로 리허설 (운영 DB 직접 복원 금지)
docker exec ktaxi-postgres sh -c 'createdb -U ktaxi ktaxi_restore_test'
docker cp /tmp/latest.dump ktaxi-postgres:/tmp/latest.dump
docker exec ktaxi-postgres pg_restore -U ktaxi -d ktaxi_restore_test --no-owner --no-acl /tmp/latest.dump
# 행수 대조 후 dropdb ktaxi_restore_test

상세는 인프라 이전 가이드 Part A 와 동일.

4운영 메모 & 한계

로그tail -f /var/log/ktaxi-backup.log
보존R2 daily/ 최신 RETENTION_COUNT(14)개만, 나머지 자동 삭제
개인키오프사이트 보관 필수(서버에 없음). 분실 시 백업 복호화 불가
RPO 한계일 1회 = 최대 24h. R2 단일 PUT ~300MB — 초과 시 S3 멀티파트 전환
이 백업은 P1 1차 방어(데이터 유실 완화). SPOF/HA 자체 해소는 아키텍처 검토의 관리형 PG 전환 또는 warm standby 필요. (이 서버는 공용 박스라 비용상 자체 PG 유지가 합리적)