Files
proxmox/scripts/nginx-proxy-manager/migrate-to-npmplus.sh
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

360 lines
15 KiB
Bash
Executable File
Raw Blame History

This file contains invisible Unicode characters
This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
#!/bin/bash
set -euo pipefail
# Load IP configuration
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
PROJECT_ROOT="$(cd "$SCRIPT_DIR/.." && pwd)"
source "${PROJECT_ROOT}/config/ip-addresses.conf" 2>/dev/null || true
# Migrate from Nginx Proxy Manager to NPMplus
# This script backs up current NPM, installs NPMplus, and migrates all configurations
set -e
PROXMOX_HOST="${PROXMOX_HOST_R630_01}"
OLD_CONTAINER_ID="105"
BACKUP_DIR="/tmp/npm-migration-$(date +%Y%m%d_%H%M%S)"
ACME_EMAIL="nsatoshi2007@hotmail.com"
TZ="America/New_York"
echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
echo "🔄 NPM to NPMplus Migration"
echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
echo ""
# Step 1: Backup current NPM
echo "📦 Step 1: Backing up current NPM configuration..."
mkdir -p "$BACKUP_DIR"
echo " 📋 Exporting proxy hosts..."
ssh root@"$PROXMOX_HOST" "pct exec $OLD_CONTAINER_ID -- 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\"
echo \"Database exported\"
else
echo \"Database not found\"
fi
'" > "$BACKUP_DIR/backup.log" 2>&1
# Copy database backup
ssh root@"$PROXMOX_HOST" "pct exec $OLD_CONTAINER_ID -- cat /tmp/npm-database.sql" > "$BACKUP_DIR/database.sql" 2>&1 || echo "Database backup may have failed"
echo " ✅ Backup complete: $BACKUP_DIR"
echo ""
# Step 2: Install NPMplus
echo "📦 Step 2: Installing NPMplus..."
echo " This will create a new container and install NPMplus via Docker Compose"
echo " Default: Alpine 3.22, 1 vCPU, 512 MB RAM, 3 GB disk"
echo ""
read -p " Continue with NPMplus installation? (y/n): " -n 1 -r
echo
if [[ ! $REPLY =~ ^[Yy]$ ]]; then
echo "❌ Migration cancelled"
exit 1
fi
echo " 🚀 Installing NPMplus..."
ssh root@"$PROXMOX_HOST" "bash -c \"
bash <(wget -qLO - https://github.com/community-scripts/ProxmoxVE/raw/main/ct/npmplus.sh)
\"" || {
echo " ❌ Installation failed. Check the output above."
exit 1
}
# Get the new container ID
echo ""
echo " 📋 Please enter the new NPMplus container ID (VMID):"
read -p " Container ID: " NEW_CONTAINER_ID
if [ -z "$NEW_CONTAINER_ID" ]; then
echo " ❌ Container ID is required"
exit 1
fi
# Wait for NPMplus to be ready
echo ""
echo " ⏳ Waiting for NPMplus to be ready (this may take 1-2 minutes)..."
for i in {1..60}; do
if ssh root@"$PROXMOX_HOST" "pct exec $NEW_CONTAINER_ID -- docker ps --filter 'name=npmplus' --format '{{.Status}}' 2>/dev/null" | grep -q "Up"; then
echo " ✅ NPMplus is running"
break
fi
echo " ⏳ Waiting... ($i/60)"
sleep 2
done
# Get the admin password
echo ""
echo " 🔑 Retrieving admin password..."
ADMIN_PASSWORD=$(ssh root@"$PROXMOX_HOST" "pct exec $NEW_CONTAINER_ID -- bash -c '
if [ -f /opt/.npm_pwd ]; then
cat /opt/.npm_pwd
else
docker logs npmplus 2>/dev/null | grep -i \"Creating a new user\" | tail -1 | grep -oP \"password: \K[^\s]+\" || echo \"\"
fi
'")
if [ -z "$ADMIN_PASSWORD" ]; then
echo " ⚠️ Could not retrieve password automatically"
echo " 📋 Check manually: ssh root@$PROXMOX_HOST \"pct exec $NEW_CONTAINER_ID -- docker logs npmplus | grep -i password\""
echo ""
read -p " Enter admin password manually: " ADMIN_PASSWORD
fi
# Get container IP
CONTAINER_IP=$(ssh root@"$PROXMOX_HOST" "pct exec $NEW_CONTAINER_ID -- hostname -I | awk '{print \$1}'")
echo " ✅ NPMplus container IP: $CONTAINER_IP"
echo " ✅ Admin password: $ADMIN_PASSWORD"
echo " 🌐 Access URL: https://$CONTAINER_IP:81"
echo ""
# Step 3: Export current configurations
echo "📦 Step 3: Exporting current NPM configurations..."
EXPORT_SCRIPT="/tmp/export-npm-configs.sh"
cat > "$EXPORT_SCRIPT" << 'EXPORT_EOF'
#!/bin/bash
# Export NPM configurations via API
NPM_URL="http://127.0.0.1:81"
EMAIL="nsatoshi2007@hotmail.com"
PASSWORD='L@ker$2010'
# Authenticate
TOKEN_RESPONSE=$(curl -s -X POST "$NPM_URL/api/tokens" \
-H "Content-Type: application/json" \
-d "{\"identity\":\"$EMAIL\",\"secret\":\"$PASSWORD\"}")
TOKEN=$(echo "$TOKEN_RESPONSE" | jq -r '.token // empty' 2>/dev/null || echo "")
if [ -z "$TOKEN" ] || [ "$TOKEN" = "null" ]; then
echo "❌ Authentication failed"
exit 1
fi
# Export proxy hosts
echo "Exporting proxy hosts..."
curl -s -X GET "$NPM_URL/api/nginx/proxy-hosts" \
-H "Authorization: Bearer $TOKEN" | jq '.' > /tmp/npm-proxy-hosts.json
# Export certificates
echo "Exporting certificates..."
curl -s -X GET "$NPM_URL/api/nginx/certificates" \
-H "Authorization: Bearer $TOKEN" | jq '.' > /tmp/npm-certificates.json
echo "✅ Export complete"
EXPORT_EOF
chmod +x "$EXPORT_SCRIPT"
scp "$EXPORT_SCRIPT" root@"$PROXMOX_HOST":/tmp/
ssh root@"$PROXMOX_HOST" "pct exec $OLD_CONTAINER_ID -- bash < /tmp/export-npm-configs.sh" || {
echo " ⚠️ Export via API failed, will use manual configuration"
}
# Copy exported files
ssh root@"$PROXMOX_HOST" "pct exec $OLD_CONTAINER_ID -- cat /tmp/npm-proxy-hosts.json" > "$BACKUP_DIR/proxy-hosts.json" 2>/dev/null || echo "{}" > "$BACKUP_DIR/proxy-hosts.json"
ssh root@"$PROXMOX_HOST" "pct exec $OLD_CONTAINER_ID -- cat /tmp/npm-certificates.json" > "$BACKUP_DIR/certificates.json" 2>/dev/null || echo "[]" > "$BACKUP_DIR/certificates.json"
echo " ✅ Configurations exported to $BACKUP_DIR"
echo ""
# Step 4: Import to NPMplus
echo "📦 Step 4: Importing configurations to NPMplus..."
echo " This will configure all 19 domains in NPMplus"
echo ""
# Create migration script for NPMplus
MIGRATE_SCRIPT="/tmp/migrate-to-npmplus-api.sh"
cat > "$MIGRATE_SCRIPT" << 'MIGRATE_EOF'
#!/bin/bash
# Migrate configurations to NPMplus
set -e
NPM_URL="https://127.0.0.1:81"
EMAIL="admin@example.org"
PASSWORD="${1}"
echo "🔐 Authenticating to NPMplus..."
TOKEN_RESPONSE=$(curl -s -k -X POST "$NPM_URL/api/tokens" \
-H "Content-Type: application/json" \
-d "{\"identity\":\"$EMAIL\",\"secret\":\"$PASSWORD\"}")
TOKEN=$(echo "$TOKEN_RESPONSE" | jq -r '.token // empty' 2>/dev/null || echo "")
if [ -z "$TOKEN" ] || [ "$TOKEN" = "null" ]; then
ERROR_MSG=$(echo "$TOKEN_RESPONSE" | jq -r '.error.message // "Unknown error"' 2>/dev/null || echo "$TOKEN_RESPONSE")
echo "❌ Authentication failed: $ERROR_MSG"
exit 1
fi
echo "✅ Authentication successful"
echo ""
# Function to create proxy host
create_proxy_host() {
local domain=$1
local scheme=$2
local hostname=$3
local port=$4
local websocket=$5
echo "📋 Processing $domain..."
# Check if exists
EXISTING=$(curl -s -k -X GET "$NPM_URL/api/nginx/proxy-hosts" \
-H "Authorization: Bearer $TOKEN" | jq -r ".result[] | select(.domain_names[] == \"$domain\") | .id" 2>/dev/null || echo "")
local HOST_ID
if [ -n "$EXISTING" ] && [ "$EXISTING" != "null" ]; then
echo " Already exists (ID: $EXISTING)"
HOST_ID=$EXISTING
else
# Create new
echo " Creating proxy host..."
RESPONSE=$(curl -s -k -X POST "$NPM_URL/api/nginx/proxy-hosts" \
-H "Authorization: Bearer $TOKEN" \
-H "Content-Type: application/json" \
-d "{
\"domain_names\": [\"$domain\"],
\"forward_scheme\": \"$scheme\",
\"forward_hostname\": \"$hostname\",
\"forward_port\": $port,
\"allow_websocket_upgrade\": $websocket,
\"block_exploits\": true,
\"cache_enabled\": false,
\"ssl_forced\": true,
\"http2_support\": true,
\"hsts_enabled\": true,
\"hsts_subdomains\": true,
\"access_list_id\": 0,
\"certificate_id\": 0
}")
HOST_ID=$(echo "$RESPONSE" | jq -r '.id // empty' 2>/dev/null || echo "")
if [ -z "$HOST_ID" ] || [ "$HOST_ID" = "null" ]; then
ERROR=$(echo "$RESPONSE" | jq -r '.error.message // .error // "Unknown error"' 2>/dev/null || echo "$RESPONSE")
echo " ❌ Failed: $ERROR"
return 1
fi
echo " ✅ Created (ID: $HOST_ID)"
fi
# Request SSL certificate
echo " 🔒 Requesting SSL certificate..."
CERT_RESPONSE=$(curl -s -k -X POST "$NPM_URL/api/nginx/certificates" \
-H "Authorization: Bearer $TOKEN" \
-H "Content-Type: application/json" \
-d "{
\"domain_names\": [\"$domain\"],
\"provider\": \"letsencrypt\",
\"letsencrypt_email\": \"nsatoshi2007@hotmail.com\",
\"letsencrypt_agree\": true
}")
CERT_ID=$(echo "$CERT_RESPONSE" | jq -r '.id // empty' 2>/dev/null || echo "")
if [ -z "$CERT_ID" ] || [ "$CERT_ID" = "null" ]; then
ERROR=$(echo "$CERT_RESPONSE" | jq -r '.error.message // .error // "Check manually\"' 2>/dev/null || echo "$CERT_RESPONSE")
echo " ⚠️ Certificate request: $ERROR"
echo " Certificate may be processing or domain may need DNS verification"
else
echo " ✅ Certificate requested (ID: $CERT_ID)"
# Update proxy host with certificate
if [ -n "$CERT_ID" ] && [ "$CERT_ID" != "null" ] && [ "$CERT_ID" != "0" ]; then
UPDATE_RESPONSE=$(curl -s -k -X PUT "$NPM_URL/api/nginx/proxy-hosts/$HOST_ID" \
-H "Authorization: Bearer $TOKEN" \
-H "Content-Type: application/json" \
-d "{
\"certificate_id\": $CERT_ID,
\"ssl_forced\": true
}")
echo " ✅ SSL configured for $domain"
fi
fi
return 0
}
# Configure all 19 domains
echo "🚀 Starting domain configuration (19 domains)..."
echo ""
SUCCESS=0
FAILED=0
# sankofa.nexus (5 domains)
create_proxy_host "sankofa.nexus" "http" "${IP_BLOCKSCOUT:-${IP_DEVICE_14:-${IP_DEVICE_14:-${IP_DEVICE_14:-${IP_DEVICE_14:-${IP_DEVICE_14:-192.168.11.14}}}}}0}" "80" "false" && ((SUCCESS++)) || ((FAILED++))
create_proxy_host "www.sankofa.nexus" "http" "${IP_BLOCKSCOUT:-${IP_DEVICE_14:-${IP_DEVICE_14:-${IP_DEVICE_14:-${IP_DEVICE_14:-${IP_DEVICE_14:-192.168.11.14}}}}}0}" "80" "false" && ((SUCCESS++)) || ((FAILED++))
create_proxy_host "phoenix.sankofa.nexus" "http" "${IP_BLOCKSCOUT:-${IP_DEVICE_14:-${IP_DEVICE_14:-${IP_DEVICE_14:-${IP_DEVICE_14:-${IP_DEVICE_14:-192.168.11.14}}}}}0}" "80" "false" && ((SUCCESS++)) || ((FAILED++))
create_proxy_host "www.phoenix.sankofa.nexus" "http" "${IP_BLOCKSCOUT:-${IP_DEVICE_14:-${IP_DEVICE_14:-${IP_DEVICE_14:-${IP_DEVICE_14:-${IP_DEVICE_14:-192.168.11.14}}}}}0}" "80" "false" && ((SUCCESS++)) || ((FAILED++))
create_proxy_host "the-order.sankofa.nexus" "http" "${IP_BLOCKSCOUT:-${IP_DEVICE_14:-${IP_DEVICE_14:-${IP_DEVICE_14:-${IP_DEVICE_14:-${IP_DEVICE_14:-192.168.11.14}}}}}0}" "80" "false" && ((SUCCESS++)) || ((FAILED++))
# d-bis.org (9 domains)
create_proxy_host "explorer.d-bis.org" "http" "${IP_BLOCKSCOUT:-${IP_DEVICE_14:-${IP_DEVICE_14:-${IP_DEVICE_14:-${IP_DEVICE_14:-${IP_DEVICE_14:-192.168.11.14}}}}}0}" "80" "false" && ((SUCCESS++)) || ((FAILED++))
create_proxy_host "rpc-http-pub.d-bis.org" "https" "${RPC_ALI_2:-${RPC_ALI_2:-${RPC_ALI_2:-${RPC_ALI_2:-${RPC_ALI_2:-${RPC_ALI_2:-${RPC_ALI_2:-192.168.11.252}}}}}}}" "443" "true" && ((SUCCESS++)) || ((FAILED++))
create_proxy_host "rpc-ws-pub.d-bis.org" "https" "${RPC_ALI_2:-${RPC_ALI_2:-${RPC_ALI_2:-${RPC_ALI_2:-${RPC_ALI_2:-${RPC_ALI_2:-${RPC_ALI_2:-192.168.11.252}}}}}}}" "443" "true" && ((SUCCESS++)) || ((FAILED++))
create_proxy_host "rpc-http-prv.d-bis.org" "https" "${RPC_ALI_1:-${RPC_ALI_1:-${RPC_ALI_1:-${RPC_ALI_1:-${RPC_ALI_1:-${RPC_ALI_1:-${RPC_ALI_1:-192.168.11.251}}}}}}}" "443" "true" && ((SUCCESS++)) || ((FAILED++))
create_proxy_host "rpc-ws-prv.d-bis.org" "https" "${RPC_ALI_1:-${RPC_ALI_1:-${RPC_ALI_1:-${RPC_ALI_1:-${RPC_ALI_1:-${RPC_ALI_1:-${RPC_ALI_1:-192.168.11.251}}}}}}}" "443" "true" && ((SUCCESS++)) || ((FAILED++))
create_proxy_host "dbis-admin.d-bis.org" "http" "${IP_DBIS_FRONTEND:-${IP_SERVICE_13:-${IP_SERVICE_13:-${IP_SERVICE_13:-${IP_SERVICE_13:-${IP_SERVICE_13:-192.168.11.13}}}}}0}" "80" "false" && ((SUCCESS++)) || ((FAILED++))
create_proxy_host "dbis-api.d-bis.org" "http" "${IP_DBIS_API:-${IP_DBIS_API:-192.168.11.155}}" "3000" "false" && ((SUCCESS++)) || ((FAILED++))
create_proxy_host "dbis-api-2.d-bis.org" "http" "${IP_DBIS_API_2:-${IP_DBIS_API_2:-192.168.11.156}}" "3000" "false" && ((SUCCESS++)) || ((FAILED++))
create_proxy_host "secure.d-bis.org" "http" "${IP_DBIS_FRONTEND:-${IP_SERVICE_13:-${IP_SERVICE_13:-${IP_SERVICE_13:-${IP_SERVICE_13:-${IP_SERVICE_13:-192.168.11.13}}}}}0}" "80" "false" && ((SUCCESS++)) || ((FAILED++))
# mim4u.org (4 domains)
create_proxy_host "mim4u.org" "http" "${IP_SERVICE_36:-${IP_SERVICE_36:-${IP_SERVICE_36:-${IP_SERVICE_36:-${IP_SERVICE_36:-${IP_SERVICE_36:-192.168.11.36}}}}}}" "80" "false" && ((SUCCESS++)) || ((FAILED++))
create_proxy_host "www.mim4u.org" "http" "${IP_SERVICE_36:-${IP_SERVICE_36:-${IP_SERVICE_36:-${IP_SERVICE_36:-${IP_SERVICE_36:-${IP_SERVICE_36:-192.168.11.36}}}}}}" "80" "false" && ((SUCCESS++)) || ((FAILED++))
create_proxy_host "secure.mim4u.org" "http" "${IP_SERVICE_36:-${IP_SERVICE_36:-${IP_SERVICE_36:-${IP_SERVICE_36:-${IP_SERVICE_36:-${IP_SERVICE_36:-192.168.11.36}}}}}}" "80" "false" && ((SUCCESS++)) || ((FAILED++))
create_proxy_host "training.mim4u.org" "http" "${IP_SERVICE_36:-${IP_SERVICE_36:-${IP_SERVICE_36:-${IP_SERVICE_36:-${IP_SERVICE_36:-${IP_SERVICE_36:-192.168.11.36}}}}}}" "80" "false" && ((SUCCESS++)) || ((FAILED++))
# defi-oracle.io (1 domain)
create_proxy_host "rpc.public-0138.defi-oracle.io" "https" "${RPC_ALI_2:-${RPC_ALI_2:-${RPC_ALI_2:-${RPC_ALI_2:-${RPC_ALI_2:-${RPC_ALI_2:-${RPC_ALI_2:-192.168.11.252}}}}}}}" "443" "true" && ((SUCCESS++)) || ((FAILED++))
echo ""
echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
echo "📊 Configuration Summary"
echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
echo "✅ Successful: $SUCCESS"
echo "⚠️ Failed: $FAILED"
echo "📋 Total: 19"
echo ""
echo "⏳ SSL certificates may take 1-2 minutes to be issued"
MIGRATE_EOF
chmod +x "$MIGRATE_SCRIPT"
scp "$MIGRATE_SCRIPT" root@"$PROXMOX_HOST":/tmp/
echo " 🚀 Running migration script in NPMplus container..."
ssh root@"$PROXMOX_HOST" "pct exec $NEW_CONTAINER_ID -- bash < /tmp/migrate-to-npmplus-api.sh '$ADMIN_PASSWORD'" || {
echo " ⚠️ Migration script had issues. Check output above."
}
echo ""
echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
echo "✅ Migration Complete!"
echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
echo ""
echo "📋 Summary:"
echo " • Old NPM Container: $OLD_CONTAINER_ID"
echo " • New NPMplus Container: $NEW_CONTAINER_ID"
echo " • NPMplus IP: $CONTAINER_IP"
echo " • Access URL: https://$CONTAINER_IP:81"
echo " • Admin Email: admin@example.org"
echo " • Admin Password: $ADMIN_PASSWORD"
echo " • Backup Location: $BACKUP_DIR"
echo ""
echo "⚠️ Next Steps:"
echo " 1. Update UDM Pro port forwarding to point to new container IP"
echo " 2. Test all domains and SSL certificates"
echo " 3. Update all scripts to use new container ID"
echo " 4. (Optional) Stop old NPM container after verification"
echo ""