Files
proxmox/docs/04-configuration/NPMPLUS_BACKUP_RESTORE.md
defiQUG fbda1b4beb
Some checks failed
Deploy to Phoenix / deploy (push) Has been cancelled
docs: Ledger Live integration, contract deploy learnings, NEXT_STEPS updates
- ADD_CHAIN138_TO_LEDGER_LIVE: Ledger form done; public code review repo bis-innovations/LedgerLive; init/push commands
- CONTRACT_DEPLOYMENT_RUNBOOK: Chain 138 gas price 1 gwei, 36-addr check, TransactionMirror workaround
- CONTRACT_*: AddressMapper, MirrorManager deployed 2026-02-12; 36-address on-chain check
- NEXT_STEPS_FOR_YOU: Ledger done; steps completable now (no LAN); run-completable-tasks-from-anywhere
- MASTER_INDEX, OPERATOR_OPTIONAL, SMART_CONTRACTS_INVENTORY_SIMPLE: updates
- LEDGER_BLOCKCHAIN_INTEGRATION_COMPLETE: bis-innovations/LedgerLive reference

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-02-12 15:46:57 -08:00

495 lines
15 KiB
Markdown

# NPMplus Backup and Restore Guide
**Last Updated:** 2026-01-31
**Document Version:** 1.0
**Status:** Active Documentation
---
**Date**: 2026-01-20
**Status**: Complete Backup/Restore Procedures
**Purpose**: Backup and restore procedures for NPMplus configuration
---
## Overview
This guide provides backup and restore procedures for NPMplus (VMID 10233) configuration, including:
- NPMplus database export (SQLite)
- Proxy host configuration export (JSON via API)
- Certificate export (file copy)
- Docker volume backup
---
## NPMplus Container Information
| Property | Value |
|----------|-------|
| **VMID** | 10233 |
| **Host** | r630-01 (192.168.11.11) |
| **Internal IP (eth0)** | 192.168.11.166 |
| **Internal IP (eth1)** | 192.168.11.167 |
| **Management UI** | `https://192.168.11.166:81` |
| **Database Location** | `/data/database.sqlite` (inside container) |
| **Certificate Location** | `/data/tls/certbot/live/` (inside container) |
| **Docker Container** | `npmplus` |
---
## Backup Procedures
### Automated Backup Script
**Script Location**: `scripts/verify/backup-npmplus.sh`**CREATED**
**Manual Backup Steps**:
#### 1. NPMplus Database Export (SQLite)
**Method 1: Direct SQLite Export**:
```bash
NPMPLUS_VMID=10233
NPMPLUS_HOST=192.168.11.11
BACKUP_DIR="/tmp/npmplus-backup-$(date +%Y%m%d_%H%M%S)"
mkdir -p "$BACKUP_DIR"
# Export database
ssh root@"$NPMPLUS_HOST" "pct exec $NPMPLUS_VMID -- bash -c '
cd /app
if [ -f /data/database.sqlite ]; then
sqlite3 /data/database.sqlite \".dump\" > /tmp/npm-database.sql 2>/dev/null || echo \"Database export may have issues\"
fi
'"
# Copy database export
ssh root@"$NPMPLUS_HOST" "pct exec $NPMPLUS_VMID -- cat /tmp/npm-database.sql" > "$BACKUP_DIR/database.sql"
```
**Method 2: Copy Database File**:
```bash
# Copy entire database file
ssh root@"$NPMPLUS_HOST" "pct exec $NPMPLUS_VMID -- cat /data/database.sqlite" > "$BACKUP_DIR/database.sqlite"
```
#### 2. Proxy Host Configuration Export (JSON via API)
**Using Export Script**:
```bash
bash scripts/verify/export-npmplus-config.sh
```
**Manual Export via API**:
```bash
NPM_URL="https://192.168.11.166:81"
NPM_EMAIL="nsatoshi2007@hotmail.com"
# Note: Use .env file for credentials in production
# NPM_PASSWORD="your-password" # Set in .env file
BACKUP_DIR="/tmp/npmplus-backup-$(date +%Y%m%d_%H%M%S)"
mkdir -p "$BACKUP_DIR"
# Authenticate
TOKEN_RESPONSE=$(curl -s -k -X POST "$NPM_URL/api/tokens" \
-H "Content-Type: application/json" \
-d "{\"identity\":\"$NPM_EMAIL\",\"secret\":\"$NPM_PASSWORD\"}")
TOKEN=$(echo "$TOKEN_RESPONSE" | jq -r '.token')
# Export proxy hosts
curl -s -k -X GET "$NPM_URL/api/nginx/proxy-hosts" \
-H "Authorization: Bearer $TOKEN" | jq '.' > "$BACKUP_DIR/proxy_hosts.json"
# Export certificates
curl -s -k -X GET "$NPM_URL/api/nginx/certificates" \
-H "Authorization: Bearer $TOKEN" | jq '.' > "$BACKUP_DIR/certificates.json"
```
#### 3. Certificate Export (File Copy)
```bash
NPMPLUS_VMID=10233
NPMPLUS_HOST=192.168.11.11
BACKUP_DIR="/tmp/npmplus-backup-$(date +%Y%m%d_%H%M%S)/certs"
mkdir -p "$BACKUP_DIR"
# List all certificates
ssh root@"$NPMPLUS_HOST" "pct exec $NPMPLUS_VMID -- ls -1 /data/tls/certbot/live/" > "$BACKUP_DIR/cert_list.txt"
# Copy all certificate directories
while IFS= read -r cert_dir; do
if [ -n "$cert_dir" ] && [ "$cert_dir" != "lost+found" ]; then
mkdir -p "$BACKUP_DIR/$cert_dir"
# Copy fullchain.pem
ssh root@"$NPMPLUS_HOST" "pct exec $NPMPLUS_VMID -- cat /data/tls/certbot/live/$cert_dir/fullchain.pem" > "$BACKUP_DIR/$cert_dir/fullchain.pem"
# Copy privkey.pem
ssh root@"$NPMPLUS_HOST" "pct exec $NPMPLUS_VMID -- cat /data/tls/certbot/live/$cert_dir/privkey.pem" > "$BACKUP_DIR/$cert_dir/privkey.pem"
fi
done < "$BACKUP_DIR/cert_list.txt"
```
#### 4. Docker Volume Backup
```bash
NPMPLUS_VMID=10233
NPMPLUS_HOST=192.168.11.11
BACKUP_DIR="/tmp/npmplus-backup-$(date +%Y%m%d_%H%M%S)"
mkdir -p "$BACKUP_DIR"
# Get Docker volume name
VOLUME_NAME=$(ssh root@"$NPMPLUS_HOST" "pct exec $NPMPLUS_VMID -- docker inspect npmplus --format '{{ range .Mounts }}{{ if eq .Destination \"/data\" }}{{ .Name }}{{ end }}{{ end }}'" 2>/dev/null || echo "")
# Create volume backup (if using Docker volumes)
if [ -n "$VOLUME_NAME" ]; then
ssh root@"$NPMPLUS_HOST" "pct exec $NPMPLUS_VMID -- docker run --rm -v $VOLUME_NAME:/data -v $(pwd)/$BACKUP_DIR:/backup alpine tar czf /backup/npmplus-data.tar.gz -C /data ."
fi
```
---
## Complete Backup Script
**Create**: `scripts/verify/backup-npmplus.sh`
```bash
#!/usr/bin/env bash
# Complete NPMplus backup script
# Backs up database, proxy hosts, certificates, and Docker volumes
set -euo pipefail
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
PROJECT_ROOT="$(cd "$SCRIPT_DIR/../.." && pwd)"
# Source .env
if [ -f "$PROJECT_ROOT/.env" ]; then
set +euo pipefail
source "$PROJECT_ROOT/.env" 2>/dev/null || true
set -euo pipefail
fi
NPMPLUS_VMID="${NPMPLUS_VMID:-10233}"
NPMPLUS_HOST="${NPMPLUS_HOST:-192.168.11.11}"
NPM_URL="${NPM_URL:-https://192.168.11.166:81}"
NPM_EMAIL="${NPM_EMAIL:-nsatoshi2007@hotmail.com}"
NPM_PASSWORD="${NPM_PASSWORD:-}"
BACKUP_DIR="/tmp/npmplus-backup-$(date +%Y%m%d_%H%M%S)"
mkdir -p "$BACKUP_DIR"
echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
echo "📦 NPMplus Complete Backup"
echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
echo ""
echo "Backup directory: $BACKUP_DIR"
echo ""
# 1. Database backup
echo "1. Backing up database..."
ssh root@"$NPMPLUS_HOST" "pct exec $NPMPLUS_VMID -- bash -c '
if [ -f /data/database.sqlite ]; then
sqlite3 /data/database.sqlite \".dump\" > /tmp/npm-database.sql 2>/dev/null || echo \"Database export may have issues\"
cp /data/database.sqlite /tmp/database.sqlite 2>/dev/null || true
fi
'"
ssh root@"$NPMPLUS_HOST" "pct exec $NPMPLUS_VMID -- cat /tmp/npm-database.sql" > "$BACKUP_DIR/database.sql" 2>/dev/null || true
ssh root@"$NPMPLUS_HOST" "pct exec $NPMPLUS_VMID -- cat /tmp/database.sqlite" > "$BACKUP_DIR/database.sqlite" 2>/dev/null || true
echo "✅ Database backup complete"
echo ""
# 2. Proxy hosts and certificates via API
if [ -n "$NPM_PASSWORD" ]; then
echo "2. Backing up proxy hosts and certificates via API..."
TOKEN_RESPONSE=$(curl -s -k -X POST "$NPM_URL/api/tokens" \
-H "Content-Type: application/json" \
-d "{\"identity\":\"$NPM_EMAIL\",\"secret\":\"$NPM_PASSWORD\"}")
TOKEN=$(echo "$TOKEN_RESPONSE" | jq -r '.token // empty' 2>/dev/null || echo "")
if [ -n "$TOKEN" ] && [ "$TOKEN" != "null" ]; then
curl -s -k -X GET "$NPM_URL/api/nginx/proxy-hosts" \
-H "Authorization: Bearer $TOKEN" | jq '.' > "$BACKUP_DIR/proxy_hosts.json"
curl -s -k -X GET "$NPM_URL/api/nginx/certificates" \
-H "Authorization: Bearer $TOKEN" | jq '.' > "$BACKUP_DIR/certificates.json"
echo "✅ API backup complete"
else
echo "⚠️ API backup failed (authentication error)"
fi
else
echo "⚠️ Skipping API backup (NPM_PASSWORD not set)"
fi
echo ""
# 3. Certificate files
echo "3. Backing up certificate files..."
CERT_DIR="$BACKUP_DIR/certs"
mkdir -p "$CERT_DIR"
CERT_LIST=$(ssh root@"$NPMPLUS_HOST" "pct exec $NPMPLUS_VMID -- ls -1 /data/tls/certbot/live/ 2>/dev/null" | grep -v "lost+found" || echo "")
if [ -n "$CERT_LIST" ]; then
while IFS= read -r cert_dir; do
if [ -n "$cert_dir" ]; then
mkdir -p "$CERT_DIR/$cert_dir"
ssh root@"$NPMPLUS_HOST" "pct exec $NPMPLUS_VMID -- cat /data/tls/certbot/live/$cert_dir/fullchain.pem" > "$CERT_DIR/$cert_dir/fullchain.pem" 2>/dev/null || true
ssh root@"$NPMPLUS_HOST" "pct exec $NPMPLUS_VMID -- cat /data/tls/certbot/live/$cert_dir/privkey.pem" > "$CERT_DIR/$cert_dir/privkey.pem" 2>/dev/null || true
fi
done <<< "$CERT_LIST"
echo "✅ Certificate backup complete"
else
echo "⚠️ No certificates found"
fi
echo ""
# 4. Create backup archive
echo "4. Creating backup archive..."
cd "$(dirname "$BACKUP_DIR")"
tar czf "$(basename "$BACKUP_DIR").tar.gz" "$(basename "$BACKUP_DIR")" 2>/dev/null || true
BACKUP_ARCHIVE="$(dirname "$BACKUP_DIR")/$(basename "$BACKUP_DIR").tar.gz"
if [ -f "$BACKUP_ARCHIVE" ]; then
echo "✅ Backup archive created: $BACKUP_ARCHIVE"
echo ""
echo "Backup complete!"
echo "Directory: $BACKUP_DIR"
echo "Archive: $BACKUP_ARCHIVE"
else
echo "⚠️ Archive creation failed, backup directory available: $BACKUP_DIR"
fi
```
---
## Restore Procedures
### 1. Database Restore
**Restore SQLite Database**:
```bash
NPMPLUS_VMID=10233
NPMPLUS_HOST=192.168.11.11
BACKUP_DIR="/tmp/npmplus-backup-20260120_120000"
# Stop NPMplus (if running)
ssh root@"$NPMPLUS_HOST" "pct exec $NPMPLUS_VMID -- docker stop npmplus"
# Restore database from SQL dump
ssh root@"$NPMPLUS_HOST" "pct exec $NPMPLUS_VMID -- bash -c '
cd /app
if [ -f /data/database.sqlite ]; then
mv /data/database.sqlite /data/database.sqlite.bak
fi
'"
cat "$BACKUP_DIR/database.sql" | ssh root@"$NPMPLUS_HOST" "pct exec $NPMPLUS_VMID -- bash -c 'sqlite3 /data/database.sqlite'"
# OR restore from file copy
# ssh root@"$NPMPLUS_HOST" "pct exec $NPMPLUS_VMID -- bash -c 'cp /tmp/database.sqlite /data/database.sqlite'"
# cat "$BACKUP_DIR/database.sqlite" | ssh root@"$NPMPLUS_HOST" "pct exec $NPMPLUS_VMID -- bash -c 'cat > /data/database.sqlite'"
# Restart NPMplus
ssh root@"$NPMPLUS_HOST" "pct exec $NPMPLUS_VMID -- docker start npmplus"
```
### 2. Configuration Restore (via API)
**Restore Proxy Hosts**:
```bash
NPM_URL="https://192.168.11.166:81"
NPM_EMAIL="nsatoshi2007@hotmail.com"
# Note: Use .env file for credentials in production
# NPM_PASSWORD="your-password" # Set in .env file
BACKUP_DIR="/tmp/npmplus-backup-20260120_120000"
# Authenticate
TOKEN_RESPONSE=$(curl -s -k -X POST "$NPM_URL/api/tokens" \
-H "Content-Type: application/json" \
-d "{\"identity\":\"$NPM_EMAIL\",\"secret\":\"$NPM_PASSWORD\"}")
TOKEN=$(echo "$TOKEN_RESPONSE" | jq -r '.token')
# Create proxy hosts from backup
cat "$BACKUP_DIR/proxy_hosts.json" | jq -c '.[]' | while read -r proxy_host; do
curl -s -k -X POST "$NPM_URL/api/nginx/proxy-hosts" \
-H "Authorization: Bearer $TOKEN" \
-H "Content-Type: application/json" \
-d "$proxy_host"
done
# Request certificates (they will auto-renew)
cat "$BACKUP_DIR/certificates.json" | jq -c '.[]' | while read -r cert; do
domains=$(echo "$cert" | jq -r '.domain_names | join(",")')
# Request new certificate via API or UI
done
```
### 3. Certificate Restore
```bash
NPMPLUS_VMID=10233
NPMPLUS_HOST=192.168.11.11
BACKUP_DIR="/tmp/npmplus-backup-20260120_120000"
# Stop NPMplus
ssh root@"$NPMPLUS_HOST" "pct exec $NPMPLUS_VMID -- docker stop npmplus"
# Restore certificates
CERT_DIR="$BACKUP_DIR/certs"
if [ -d "$CERT_DIR" ]; then
for cert_dir in "$CERT_DIR"/*; do
if [ -d "$cert_dir" ]; then
cert_name=$(basename "$cert_dir")
mkdir -p /tmp/cert_restore
cp "$cert_dir/fullchain.pem" /tmp/cert_restore/fullchain.pem
cp "$cert_dir/privkey.pem" /tmp/cert_restore/privkey.pem
ssh root@"$NPMPLUS_HOST" "pct exec $NPMPLUS_VMID -- mkdir -p /data/tls/certbot/live/$cert_name"
cat /tmp/cert_restore/fullchain.pem | ssh root@"$NPMPLUS_HOST" "pct exec $NPMPLUS_VMID -- bash -c 'cat > /data/tls/certbot/live/$cert_name/fullchain.pem'"
cat /tmp/cert_restore/privkey.pem | ssh root@"$NPMPLUS_HOST" "pct exec $NPMPLUS_VMID -- bash -c 'cat > /data/tls/certbot/live/$cert_name/privkey.pem'"
fi
done
fi
# Restart NPMplus
ssh root@"$NPMPLUS_HOST" "pct exec $NPMPLUS_VMID -- docker start npmplus"
```
---
## Disaster Recovery Scenarios
### Scenario 1: NPMplus Container Lost (VMID Recreated)
**Restore Steps**:
1. **Recreate Container**:
- Install NPMplus on new container (VMID)
- Get new IP address
- Update UDM Pro port forwarding (if IP changed)
2. **Restore Database**:
- Copy database backup to new container
- Restore as described above
3. **Restore Certificates**:
- Copy certificate files to new container
- Restore as described above
4. **Verify Configuration**:
- Run verification scripts
- Test all domains
### Scenario 2: NPMplus Database Corrupted
**Restore Steps**:
1. **Stop NPMplus**:
```bash
ssh root@192.168.11.11 "pct exec 10233 -- docker stop npmplus"
```
2. **Backup Current Database**:
```bash
ssh root@192.168.11.11 "pct exec 10233 -- cp /data/database.sqlite /data/database.sqlite.corrupted"
```
3. **Restore from Backup**:
- Restore database as described above
4. **Verify and Test**:
- Start NPMplus
- Verify all proxy hosts exist
- Test domains
### Scenario 3: Certificate Files Lost
**Restore Steps**:
1. **If Backup Available**:
- Restore certificate files as described above
2. **If No Backup Available**:
- Re-request certificates via NPMplus UI or API
- Certificates will auto-renew from Let's Encrypt
---
## Backup Schedule Recommendations
### Recommended Backup Schedule
| Backup Type | Frequency | Retention | Location |
|-------------|-----------|-----------|----------|
| Complete Backup | Weekly | 4 weeks | `/tmp/npmplus-backup-*` |
| Database Export | Daily | 7 days | Backup server or cloud storage |
| Configuration Export (API) | After each change | 30 days | Version control or config management |
| Certificate Export | Monthly | 90 days | Secure storage (encrypted) |
### Automated Backup Script
**Create cron job for daily backups**:
```bash
# Add to crontab (crontab -e)
0 2 * * * /home/intlc/projects/proxmox/scripts/verify/backup-npmplus.sh >> /var/log/npmplus-backup.log 2>&1
```
### Backup Retention Policy
- **Daily backups**: Keep 7 days
- **Weekly backups**: Keep 4 weeks
- **Monthly backups**: Keep 3 months
- **Before major changes**: Keep indefinitely
---
## Verification After Restore
After restore, verify:
1. **NPMplus Container Status**:
```bash
ssh root@192.168.11.11 "pct exec 10233 -- docker ps | grep npmplus"
```
2. **Proxy Hosts**:
```bash
bash scripts/verify/export-npmplus-config.sh
```
3. **Certificates**:
```bash
# Check certificate files exist
ssh root@192.168.11.11 "pct exec 10233 -- ls -la /data/tls/certbot/live/"
```
4. **End-to-End Tests**:
```bash
bash scripts/verify/verify-end-to-end-routing.sh
```
---
## Related Documentation
- **Verification Runbook**: `docs/04-configuration/INGRESS_VERIFICATION_RUNBOOK.md`
- **NPMplus Setup**: `docs/04-configuration/NPMPLUS_COMPLETE_SETUP_SUMMARY.md`
- **Backup Scripts**: `scripts/verify/backup-npmplus.sh` (to be created)
---
**Last Updated**: 2026-01-20
**Maintained By**: Infrastructure Team
**Status**: Complete Backup/Restore Procedures