← 전체 글로 돌아가기

웹 개발

VPS 백업 파일로 실제 복구를 해 보니 빠진 설정이 있었다

매일 DB 덤프만 믿고 있다가 임시 서버에서 복구 리허설을 하면서 업로드 파일과 환경 변수 관리의 중요성을 알게 됐다.

시작

처음에는 매일 새벽 DB 덤프가 만들어지고 있으니 어느 정도 안심했다. 그런데 서버 이전을 준비하면서 "이 파일로 진짜 복구가 되나?"라는 질문에 바로 답을 못 했다. 그래서 운영 서버를 건드리지 않고 임시 VPS 하나를 만들어 복구 리허설을 했다.

가장 당황한 부분은 덤프 파일 자체보다 주변 설정이었다. 데이터베이스는 올라왔는데 앱이 읽는 환경 변수 이름이 예전 문서와 달랐다.

복구 리허설 순서

처음에는 파일을 임시 서버로 옮겼다.

scp backup-2026-06-26.sql.gz user@temp-server:/tmp/
ssh user@temp-server
mkdir -p ~/restore-test
cd ~/restore-test

그 다음 컨테이너를 최소 구성으로 띄웠다.

gunzip -c /tmp/backup-2026-06-26.sql.gz > dump.sql
docker compose up -d db
docker compose exec -T db psql -U app app < dump.sql

복구가 끝났다고 바로 성공 처리하지 않고, 실제 앱이 필요한 테이블 수와 최근 데이터 몇 개를 확인했다.

docker compose exec db psql -U app app -c "select count(*) from posts;"
docker compose exec db psql -U app app -c "select created_at, title from posts order by created_at desc limit 3;"

발견한 빠진 항목

복구 중 발견한 문제는 세 가지였다.

  • .env.example에 운영에서만 쓰는 DATABASE_SSL 설명이 없었다.
  • 업로드 파일 경로를 DB 덤프와 별도로 보관해야 했다.
  • 새 서버의 타임존이 UTC라 로그 시간이 운영 기록과 어긋났다.

특히 업로드 파일은 DB 안에 경로만 있고 실제 파일은 볼륨에 있었다. 덤프만 잘 떠도 이미지가 깨질 수 있다는 뜻이다.

백업 절차 정비

백업 스크립트 옆에 복구 명령도 같이 적었다. 그리고 백업 성공 로그에 파일 크기만 남기지 않고, 마지막으로 복구 테스트한 날짜를 따로 기록하기로 했다.

du -h /backup/latest.sql.gz
ls -lh /backup/uploads-latest.tar.gz

결론

백업은 "언젠가 필요하면 쓰겠지"가 아니라 "새 서버에서 몇 분 안에 재현할 수 있는 절차"에 가까웠다. 작은 서비스라도 복구 리허설을 한 번 해 두면, 장애가 났을 때 검색부터 시작하지 않아도 된다.