Geo-MLOps 의 모든 상태는 두 곳에 있습니다. Postgres(앱과 MLflow 가 함께 쓰는 DB)와 RustFS(데이터셋·이미지 레이어·모델 아티팩트·빌드 로그·엣지 업로드)입니다. 둘 다 Docker 볼륨에만 있어서, MLflow 실험 영구 삭제나 테넌트 삭제처럼 실수로 지운 것은 백업 없이는 되돌릴 수 없습니다. Compose 는 백업을 하지 않으므로, 소스에 함께 들어 있는 백업 스크립트와 systemd 타이머를 설치합니다.

무엇을 어떻게 받나

대상방식보존
Postgres컨테이너 안의 pg_dump -FcBACKUP_DIR/postgres/mlflow-<UTC시각>.dump 에 저장. 받자마자 pg_restore --list 로 읽어 보고, 깨진 파일은 남기지 않음BACKUP_KEEP_DAYS(기본 14일)보다 오래된 덤프는 지움
RustFS버킷마다 aws s3 syncBACKUP_DIR/objects/<버킷>/ 에 복사추가만 합니다(--delete 없음). 지운 객체도 미러에 남습니다. 공간이 모자라면 손으로 정리
  • 매일 03:30(최대 15분 무작위 지연)에 돕니다. 서버가 꺼져 있던 밤의 백업은 다음 부팅 때 따라잡습니다.
  • 낮은 우선순위(Nice=10, I/O idle)로 돌아 학습·요청과 디스크를 다투지 않습니다.
  • pg_dump 는 Postgres 컨테이너 안의 것을, S3 복사는 AWS CLI 컨테이너를 씁니다. 서버에 따로 설치할 것이 없습니다.

설치 (서버에서 한 번)

  1. 스크립트와 유닛 파일을 설치합니다.

    D=/opt/geo-mlops/deploy/backup
    sudo install -m 0755 $D/backup.sh /usr/local/sbin/geo-mlops-backup
    sudo install -m 0644 $D/geo-mlops-backup.service /etc/systemd/system/
    sudo install -m 0644 $D/geo-mlops-backup.timer /etc/systemd/system/
  2. 기본값과 다르게 쓸 것이 있으면 /etc/geo-mlops/backup.env 에 적습니다(없어도 됩니다).

    sudo tee /etc/geo-mlops/backup.env >/dev/null <<'ENV'
    BACKUP_DIR=/mnt/backup/geo-mlops
    BACKUP_KEEP_DAYS=14
    ENV
  3. 타이머를 켜고, 첫 백업을 지금 한 번 돌려 확인합니다.

    sudo systemctl daemon-reload
    sudo systemctl enable --now geo-mlops-backup.timer
    sudo systemctl start geo-mlops-backup.service
    journalctl -u geo-mlops-backup.service -n 20      # 마지막 줄 "backup finished"
    systemctl list-timers geo-mlops-backup.timer      # 다음 실행 시각

backup.env 로 바꿀 수 있는 값

변수기본값
BACKUP_DIR/var/backups/geo-mlops백업이 쌓일 곳
BACKUP_KEEP_DAYS14DB 덤프 보존 일수
BACKUP_BUCKETS(비움 = 모든 버킷)공백으로 구분한 버킷 이름
BACKUP_SKIP_OBJECTS01 이면 DB 만 백업
PG_CONTAINER / PG_USER / PG_DBgeo-mlops-mlflow-postgres / mlflow / mlflowPostgres 컨테이너와 계정
S3_ENDPOINT / S3_ACCESS_KEY / S3_SECRET_KEYhttp://localhost:9000 / rustfsadmin / rustfsadminRustFS 접속 정보. Compose 의 계정을 바꿨다면 여기도 바꿉니다
AWS_CLI_IMAGEamazon/aws-cli:2.34.63S3 복사에 쓸 이미지

복구

데이터베이스

앱을 멈춰 DB 를 쓰는 쪽이 없게 한 뒤 덤프를 되돌립니다.

docker stop geo-mlops-app
docker exec -i geo-mlops-mlflow-postgres \
    pg_restore -U mlflow -d mlflow --clean --if-exists --no-owner \
    < /var/backups/geo-mlops/postgres/mlflow-<UTC시>.dump
docker start geo-mlops-app

객체

버킷 하나(또는 그 안의 접두사)를 미러에서 되올립니다. 미러는 추가만 하므로, 백업 시점 이후에 지운 객체도 되살아납니다. 필요한 접두사만 골라 올리세요.

docker run --rm --network host -v /var/backups/geo-mlops/objects:/backup \
    -e AWS_ACCESS_KEY_ID=rustfsadmin -e AWS_SECRET_ACCESS_KEY=rustfsadmin \
    -e AWS_DEFAULT_REGION=us-east-1 -e AWS_REQUEST_CHECKSUM_CALCULATION=when_required \
    amazon/aws-cli:2.34.63 --endpoint-url http://localhost:9000 \
    s3 sync /backup/datasets/<tenant_id>/<dataset_id>/ s3://datasets/<tenant_id>/<dataset_id>/

복구 연습 (분기마다)

복구가 되는지 모르는 백업은 백업이 아닙니다. 분기에 한 번, 운영 서버가 아닌 곳에서 덤프가 읽히는지 확인합니다.

BACKUP_DIR=/tmp/geo-backup-drill BACKUP_BUCKETS=build-logs /usr/local/sbin/geo-mlops-backup
docker exec -i geo-mlops-mlflow-postgres pg_restore --list \
    < /tmp/geo-backup-drill/postgres/mlflow-*.dump | head

다음: 앞단 프록시 주의

2026-09-21 기준 플랫폼에 맞춰 작성했습니다.

© Geo-MLOps