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

15 KiB

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:

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:

# 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 scripts/verify/export-npmplus-config.sh

Manual Export via API:

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)

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

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

#!/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:

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:

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

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:
ssh root@192.168.11.11 "pct exec 10233 -- docker stop npmplus"
  1. Backup Current Database:
ssh root@192.168.11.11 "pct exec 10233 -- cp /data/database.sqlite /data/database.sqlite.corrupted"
  1. Restore from Backup:

    • Restore database as described above
  2. 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

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:

# 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:
ssh root@192.168.11.11 "pct exec 10233 -- docker ps | grep npmplus"
  1. Proxy Hosts:
bash scripts/verify/export-npmplus-config.sh
  1. Certificates:
# Check certificate files exist
ssh root@192.168.11.11 "pct exec 10233 -- ls -la /data/tls/certbot/live/"
  1. End-to-End Tests:
bash scripts/verify/verify-end-to-end-routing.sh

  • 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