# DR-Harbor — Harbor Registry 資料毀損還原 SOP

**目標時間**: < 30 分鐘  
**觸發場景**: Harbor 資料毀損、container image 消失，或 harbor-data volume 損壞  
**工具**: rsync, docker compose  
**最後更新**: 2026-04-11 (Claude Sonnet 4.6 Asia/Taipei)

---

## 前提確認

```bash
# 確認 188 上的 rsync 備份存在
ls -lh /backup/110/harbor/
# 期望：有檔案，最近修改時間 < 25 小時

# 確認最後備份時間
cat /var/run/backup-110.last_success | xargs -I{} date -d @{}
```

---

## 步驟 1：停止 Harbor（2 分鐘）

```bash
ssh wooo@192.168.0.110 "cd /opt/harbor && docker compose down"
```

---

## 步驟 2：備份現有損壞資料（1 分鐘）

```bash
ssh wooo@192.168.0.110 \
  "sudo mv /var/lib/docker/volumes/harbor_harbor-data \
           /var/lib/docker/volumes/harbor_harbor-data.bak.$(date +%Y%m%d)"
```

---

## 步驟 3：從 188 rsync 備份還原到 110（15 分鐘）

```bash
# 在 188 執行（rsync 方向：188 備份 → 110）
rsync -avz \
  /backup/110/harbor/ \
  wooo@192.168.0.110:/var/lib/docker/volumes/harbor_harbor-data/_data/
```

---

## 步驟 4：重啟 Harbor（5 分鐘）

```bash
ssh wooo@192.168.0.110 "cd /opt/harbor && docker compose up -d"

# 等待 Harbor 就緒
for i in $(seq 1 12); do
  CODE=$(curl -s -o /dev/null -w '%{http_code}' http://192.168.0.110:5000 2>/dev/null)
  [ "$CODE" = "200" ] || [ "$CODE" = "301" ] && echo "✅ Harbor ready" && break
  echo "⏳ 等待 Harbor... ($i/12)"; sleep 10
done
```

---

## 步驟 5：驗收

```bash
# 確認 images 存在
curl -s http://192.168.0.110:5000/v2/_catalog | python3 -m json.tool

# 驗證 CD pipeline 可 pull（下一次部署自動驗證）
docker pull 192.168.0.110:5000/awoooi/api:latest
```

---

## 預防

- `scripts/ops/backup-from-110.sh` 每天凌晨 1:00 在 188 執行
- 備份失敗時觸發 Telegram 告警
- 若 rsync 備份超過 25 小時未更新，Prometheus `BackupFailed` 告警觸發
