| 대상 | 위치 | 이유 |
|---|---|---|
| 설정 | conf/, /etc/nginx/conf.d |
복원 불가, 가장 자주 바뀜 |
| 현재 릴리스 | current/app.jar |
빌드 서버 없이 롤백 |
| DB 덤프 | pg_dump·expdp 결과 |
데이터 |
| 유닛·cron | /etc/systemd/system, /etc/cron.d |
서버 재구축 |
| 업로드 파일 | data/ |
사용자 자료 |
로그와 임시 파일은 뺍니다. 릴리스는 releases/ 전체가 아니라 현재 것만 넣고 나머지는 빌드 산출물 저장소에 있습니다.
복사본 3개, 매체 2종류, 그중 1개는 다른 장소입니다. 서버 한 대 안에만 있는 백업은 서버가 죽으면 같이 죽습니다.
rsync -avz /backup/myapp/ backup-host:/backup/app1/ # 다른 서버로폐쇄망은 NAS 나 백업 서버가 그 "다른 장소" 입니다. 명령어 묶음 06 의 rsync 로 백업 폴더를 매일 동기화합니다.
| 용어 | 뜻 | 정하는 것 |
|---|---|---|
| RPO | 잃어도 되는 시간 | 백업 주기 |
| RTO | 복구까지 걸리는 시간 | 복구 절차의 자동화 정도 |
설정은 하루 한 번이면 RPO 1일이고, DB 는 1시간마다 덤프하면 RPO 1시간입니다. RTO 는 복구 연습을 해 봐야 측정됩니다. 이 두 숫자를 정해 두면 "얼마나 자주, 얼마나 빨리" 가 결정됩니다.
설정·jar·덤프를 각각 두면 어느 것이 같은 시점인지 모릅니다. 한 tar 에 넣고 시각·호스트·경로를 적은 MANIFEST 를 함께 둡니다.
printf 'stamp=%s\nhost=%s\napp_home=%s\n' "$STAMP" "$(hostname)" "$APP_HOME" > "$work/MANIFEST"
tar czf "$BACKUP_DIR/myapp-$STAMP.tgz" -C "$work" .복구 때 tar xzOf 파일 ./MANIFEST 로 어느 서버의 언제 것인지 풀지 않고 확인합니다.
sha256sum "$out" > "$out.sha256" # 만들 때
sha256sum -c "$out.sha256" # 확인할 때
tar tzf "$out" > /dev/null # 목록이 끝까지 읽히는지체크섬은 옮기다 바뀐 것을, tar tzf 는 잘린 파일을 잡습니다. 둘 다 통과한 것만 복구 후보입니다. 명령어 묶음 07 의 도구가 백업의 핵심입니다.
| DB | 덤프 | 복구 |
|---|---|---|
| PostgreSQL | pg_dump -U app appdb > db.sql |
psql -U app appdb < db.sql |
| MySQL | mysqldump -u app appdb > db.sql |
mysql -u app appdb < db.sql |
| Oracle | expdp app/pw dumpfile=app.dmp |
impdp app/pw dumpfile=app.dmp |
큰 DB 는 앱 서버가 아니라 DB 서버에서 DBA 가 백업합니다. 앱 서버에서는 앱이 쓰는 스키마만 덤프해 설정과 시점을 맞추는 용도입니다. 스크립트는 DB_DUMP_CMD 변수로 명령을 받아 비어 있으면 건너뜁니다.
백업을 운영 폴더에 바로 풀면 현재 상태가 사라져 비교할 수 없습니다. 먼저 다른 폴더에 풀고 diff 로 확인한 뒤 필요한 파일만 옮깁니다.
bash backup.sh restore /backup/myapp/myapp-20260911_094945.tgz /tmp/restore
diff -r /tmp/restore/conf /opt/myapp/conf
cp /tmp/restore/conf/application.yml /opt/myapp/conf/diff -r 이 무엇이 달라졌는지 보여 줍니다. 설정 한 줄 되돌리기라면 파일 하나만 옮기면 됩니다.
find "$BACKUP_DIR" -name 'myapp-*.tgz*' -mtime +30 -delete매일 백업이면 30일치가 30개입니다. 운영 묶음 06 의 -mtime 삭제와 같은 형태이고 .sha256 도 함께 지우도록 패턴에 * 를 붙였습니다. 월말 것은 따로 옮겨 1년 보관하는 정책을 흔히 씁니다.
# /etc/cron.d/myapp-backup
PATH=/usr/local/bin:/usr/bin:/bin
30 2 * * * myapp /opt/myapp/bin/backup.sh run >> /var/log/myapp/backup.log 2>&1
0 3 * * * myapp rsync -az /backup/myapp/ backup-host:/backup/app1/ >> /var/log/myapp/backup.log 2>&1새벽에 백업하고 30분 뒤 원격으로 보냅니다. 실패는 로그의 [ERROR] 줄로 남고, 10 레슨의 월간 점검에 "최근 백업 파일 날짜" 를 넣어 백업이 멈춘 것을 발견합니다.
분기에 한 번 실제로 복구해 봅니다. 순서를 문서로 두고 걸린 시간을 적으면 그것이 RTO 입니다.
verifyrestorediff -r 로 운영과 비교4단계까지 가야 "jar 가 뜨는가", "설정에 빠진 키가 없는가" 를 알 수 있습니다.
서버를 새로 받았을 때 복구 순서입니다. 백업 묶음 밖의 것도 필요합니다.
| 순서 | 항목 | 출처 |
|---|---|---|
| 1 | OS·패키지 | dnf install 목록 |
| 2 | 계정·권한 | 명령어 묶음 03 절차 |
| 3 | 유닛·cron·nginx | /etc 백업 |
| 4 | 앱 설정·jar | 백업 묶음 |
| 5 | 방화벽·SELinux | 10 레슨 명령 |
rpm -qa > packages.txt 와 /etc 의 앱 관련 파일을 백업에 넣어 두면 1·3 단계가 빨라집니다.
가상 머신이나 스토리지 스냅샷은 서버 전체를 되돌리지만 파일 하나만 꺼내기는 어렵고 DB 정합성이 보장되지 않을 수 있습니다. 파일 백업은 그 반대입니다.
둘은 대체가 아니라 보완입니다. 스냅샷은 패치·큰 변경 직전에, 파일 백업은 매일 돌립니다.