백업과 복구
PlantPulse Studio 는 백업 스크립트 한 개와 복구 스크립트 한 개로 전체 상태를 다룹니다.
모든 명령은 설치 디렉터리(/opt/kopens/plantpulse-studio-docker)에서 실행합니다.
무엇이 백업되는가
백업 파일 하나(dist/backup-<날짜>.tar.gz)에 아래가 모두 들어갑니다.
| 대상 | 내용 |
|---|---|
| PostgreSQL 전체 덤프 | 사용자 계정 · 대화 이력 · 와처 · 알림 읽음 상태 · 스킬 · 배포 이력 · 감사 로그 |
워크스페이스(workspaces/) | 프로젝트별 실제 소스코드 · 채팅 첨부 파일 |
빌드 산출물(builds/) | 배포된 앱의 각 버전(롤백에 필요) |
상태 디렉터리(state/) | settings.json(환경설정) · 감사/사용량 로그 · 커스텀 템플릿 · 브랜딩 로고 |
PostgreSQL 의 데이터 디렉터리 자체는 아카이브에서 제외됩니다 — SQL 덤프로 대체되기 때문입니다.
아카이브 안에는 전 사용자의 워크스페이스가 통째로 들어가고, 예전 설치에서 넘어온
경우 settings.json 에 API 키가 남아 있을 수 있습니다.
- 스크립트가 백업 파일을
600(소유자만 읽기),dist/디렉터리를700으로 만듭니다. - 외부 매체·다른 서버로 옮길 때도 이 권한을 유지하세요.
(
scp -p,rsync -a,tar -p등 권한 보존 옵션 사용) - 사외로 반출한다면 별도 암호화를 권장합니다.
백업 실행
cd /opt/kopens/plantpulse-studio-docker
bash bin/backup.sh
▶ PostgreSQL 덤프
▶ 파일 상태 아카이브(postgres 데이터 제외 — 덤프로 대체)
-rw------- 1 root root 78M ... dist/backup-20260728-031501.tar.gz
✅ 백업 완료 (보존 14개)
- 결과물:
dist/backup-<YYYYMMDD-HHMMSS>.tar.gz - 보존 정책: 최신 14개만 남기고 오래된 파일은 자동 삭제됩니다(
BACKUP_KEEP로 조정). - 번들 PostgreSQL 을 쓰는 경우 스택이 떠 있어야 덤프를 뜰 수 있습니다.
BACKUP_KEEP=30 bash bin/backup.sh # 이번 실행부터 30개 보존
이미지 업그레이드나 설정 대변경 전에 bash bin/backup.sh 를 한 번 돌려 두세요.
자동 백업 설치(권장)
매일 새벽 03:30 에 백업이 돌도록 cron 을 설치합니다. root 권한이 필요합니다.
sudo bash bin/install-backup-cron.sh
[backup-cron] 설치 완료 — 스케줄: '30 3 * * *', 보존 14개, 로그: dist/backup.log
시간·보존 개수를 바꾸려면,
sudo BACKUP_CRON="0 4 * * *" BACKUP_KEEP=30 bash bin/install-backup-cron.sh
제거는,
sudo bash bin/install-backup-cron.sh remove
동작 여부는 로그로 확인합니다.
tail -50 /opt/kopens/plantpulse-studio-docker/dist/backup.log
ls -lh /opt/kopens/plantpulse-studio-docker/dist/backup-*.tar.gz
권장 운영 주기
| 주기 | 할 일 |
|---|---|
| 매일 | 자동 백업(cron) — 14일치 보존 |
| 매주 | 최신 백업 1개를 다른 서버·매체로 복사(권한 유지) |
| 매월 | dist/ 용량과 디스크 여유 확인 |
| 분기 | DRYRUN=1 복구 리허설 — 아래 참조 |
| 업그레이드 전 | 수동 백업 1회 |
백업 파일이 매일 쌓이고 있어도 실제로 복구되는지는 해 보기 전엔 알 수 없습니다. 분기마다 리허설을 돌리세요. 비파괴이므로 운영 중에 실행해도 안전합니다.
복구 리허설 (비파괴)
아카이브 구조와 데이터베이스 도달성만 검사하고 아무것도 바꾸지 않습니다.
DRYRUN=1 bash bin/restore.sh # 최신 백업 대상
DRYRUN=1 bash bin/restore.sh dist/backup-20260712-191858.tar.gz
▶ 아카이브 검증
ppstudio.sql 12M · files.tar.gz 66M
▶ DRYRUN — DB 도달성만 확인
✅ DB 도달 OK
✅ DRYRUN 통과 — 실제 복구는 DRYRUN 없이 실행
복구 실행
현재 데이터베이스 내용과 데이터 디렉터리 전체를 백업 시점으로 덮어씁니다. 복구 이후에 만들어진 프로젝트·대화·배포는 사라집니다.
cd /opt/kopens/plantpulse-studio-docker
bash bin/restore.sh # 최신 백업으로 복구
bash bin/restore.sh dist/backup-20260712-191858.tar.gz # 특정 시점으로 복구
확인 프롬프트에 restore 를 입력해야 진행됩니다.
⚠ 현재 DB 와 /var/lib/pp-studio 파일 상태를 이 백업으로 덮어씁니다: dist/backup-...
계속하려면 'restore' 를 입력하세요:
스크립트가 수행하는 순서입니다.
- 아카이브 구조 검증(덤프·파일 아카이브 존재 확인)
- 현재 파일 상태를
dist/pre-restore-<날짜>.tar.gz로 자동 대피 - 스택 정지
- 데이터 디렉터리 복구 → 데이터베이스 복구
- 스택 기동 → 헬스 확인
자동화 스크립트 안에서 프롬프트 없이 실행하려면,
FORCE=1 bash bin/restore.sh dist/backup-20260712-191858.tar.gz
복구 직후 헬스가 안 뜬다면
bash bin/logs.sh # 서버 로그 확인
bash bin/status.sh
되돌리려면 2단계에서 만들어진 대피본으로 다시 복구합니다. 단, 대피본은 파일 상태만 담고 있습니다(데이터베이스는 포함되지 않습니다).
bash bin/restore.sh dist/pre-restore-20260728-104233.tar.gz
다른 서버로 이전하기
- 새 서버에 같은 버전으로 스택을 설치합니다(설치 또는 에어갭 설치).
- 기존 서버의
.env를 새 서버로 복사합니다(권한600유지). - 백업 아카이브를 새 서버의
dist/로 복사합니다(권한600유지). - 복구를 실행합니다.
cd /opt/kopens/plantpulse-studio-docker
DRYRUN=1 bash bin/restore.sh dist/backup-20260728-031501.tar.gz # 먼저 리허설
bash bin/restore.sh dist/backup-20260728-031501.tar.gz
이전 후 접속 주소가 달라지면 모든 사용자가 로그아웃 후 재로그인을 한 번 해야 합니다 — 로그인 쿠키는 발급 시점의 호스트 전용이라 그대로 두면 데이터 요청이 401 이 됩니다. 자세한 내용은 도메인과 리버스 프록시 참조.
디스크 관리
백업은 워크스페이스와 빌드 산출물을 통째로 담기 때문에 프로젝트가 늘수록 커집니다.
du -sh /opt/kopens/plantpulse-studio-docker/dist
du -sh /var/lib/pp-studio/*
df -h /var/lib/pp-studio
- 보존 개수를 줄이려면 cron 을
BACKUP_KEEP값과 함께 다시 설치하세요. - 배포 앱의 과거 버전은 프로젝트당 기본 10개까지만 보관되고 초과분은 자동 정리됩니다 (현재 서비스 중인 버전은 항상 보존).