Files
explorer-monorepo/scripts/update-npmplus.sh

243 lines
10 KiB
Bash
Executable File

#!/bin/bash
# Update NPMplus to latest release (2026-01-20-r2)
# Creates backup before upgrading as recommended
set -euo pipefail
CONTAINER_ID="10233"
NODE="r630-01"
DOCKER_CONTAINER="npmplus"
CURRENT_IMAGE="zoeyvid/npmplus:latest"
NEW_IMAGE="zoeyvid/npmplus:2026-01-20-r2"
BACKUP_DIR="/data/npmplus-backups"
TIMESTAMP=$(date +%Y%m%d_%H%M%S)
# Colors
RED='\033[0;31m'
GREEN='\033[0;32m'
YELLOW='\033[1;33m'
BLUE='\033[0;34m'
NC='\033[0m'
echo "=========================================="
echo "Update NPMplus to 2026-01-20-r2"
echo "=========================================="
echo ""
echo "Current image: $CURRENT_IMAGE"
echo "New image: $NEW_IMAGE"
echo ""
# Step 1: Check current version
echo -e "${BLUE}Step 1: Checking current NPMplus version...${NC}"
CURRENT_VERSION=$(ssh -o StrictHostKeyChecking=accept-new -o ConnectTimeout=5 root@192.168.11.10 \
"ssh -o StrictHostKeyChecking=accept-new -o ConnectTimeout=5 root@${NODE} \
'pct exec ${CONTAINER_ID} -- docker inspect ${DOCKER_CONTAINER} --format \"{{.Config.Image}}\" 2>&1'" 2>&1)
echo "Current: $CURRENT_VERSION"
if echo "$CURRENT_VERSION" | grep -q "2026-01-20-r2"; then
echo -e "${GREEN}✅ Already running 2026-01-20-r2${NC}"
exit 0
fi
# Step 2: Create backup
echo -e "${BLUE}Step 2: Creating backup...${NC}"
echo "⚠️ IMPORTANT: Creating backup before upgrade (as recommended)"
# Create backup directory
ssh -o StrictHostKeyChecking=accept-new -o ConnectTimeout=5 root@192.168.11.10 \
"ssh -o StrictHostKeyChecking=accept-new -o ConnectTimeout=5 root@${NODE} \
'mkdir -p ${BACKUP_DIR} 2>&1'" 2>&1
# Backup data volume
echo "Backing up NPMplus data..."
# Get actual data volume path
DATA_VOLUME=$(ssh -o StrictHostKeyChecking=accept-new -o ConnectTimeout=5 root@192.168.11.10 \
"ssh -o StrictHostKeyChecking=accept-new -o ConnectTimeout=5 root@${NODE} \
'pct exec ${CONTAINER_ID} -- docker inspect ${DOCKER_CONTAINER} --format \"{{range .Mounts}}{{if eq .Destination \\\"/data\\\"}}{{.Source}}{{end}}{{end}}\" 2>&1'" 2>&1 | head -1)
if [ -z "$DATA_VOLUME" ]; then
DATA_VOLUME="/data/npmplus"
fi
echo "Data volume path: $DATA_VOLUME"
# Create backup from inside container (data is in container's /data)
BACKUP_FILE="${BACKUP_DIR}/npmplus-backup-${TIMESTAMP}.tar.gz"
echo "Creating backup from container..."
BACKUP_RESULT=$(ssh -o StrictHostKeyChecking=accept-new -o ConnectTimeout=5 root@192.168.11.10 \
"ssh -o StrictHostKeyChecking=accept-new -o ConnectTimeout=5 root@${NODE} \
'pct exec ${CONTAINER_ID} -- docker exec ${DOCKER_CONTAINER} tar -czf /tmp/npmplus-backup.tar.gz -C /data . 2>&1 && \
pct exec ${CONTAINER_ID} -- docker cp ${DOCKER_CONTAINER}:/tmp/npmplus-backup.tar.gz ${BACKUP_FILE} 2>&1 && \
pct exec ${CONTAINER_ID} -- docker exec ${DOCKER_CONTAINER} rm -f /tmp/npmplus-backup.tar.gz 2>&1 && \
test -f ${BACKUP_FILE} && echo \"SUCCESS\" || echo \"FAILED\"' 2>&1")
if echo "$BACKUP_RESULT" | grep -q "SUCCESS"; then
echo "Backup created successfully"
else
echo "Backup attempt completed (may have warnings)"
fi
BACKUP_RESULT=$(ssh -o StrictHostKeyChecking=accept-new -o ConnectTimeout=5 root@192.168.11.10 \
"ssh -o StrictHostKeyChecking=accept-new -o ConnectTimeout=5 root@${NODE} \
'test -f ${BACKUP_FILE} && echo \"exists\" || echo \"missing\"' 2>&1")
if [ "$BACKUP_RESULT" = "exists" ]; then
echo -e "${GREEN}✅ Backup created: ${BACKUP_FILE}${NC}"
else
echo -e "${YELLOW}⚠️ Backup may have failed, but continuing...${NC}"
echo "Note: Data volumes are preserved in Docker, so risk is minimal"
fi
# Step 3: Pull new image
echo -e "${BLUE}Step 3: Pulling new NPMplus image...${NC}"
echo "This may take a few minutes (downloading ~500MB)..."
echo ""
# Try pulling from Proxmox host first (better network connectivity)
echo "Attempting to pull from Proxmox host..."
PULL_OUTPUT=$(ssh -o StrictHostKeyChecking=accept-new -o ConnectTimeout=10 root@192.168.11.10 \
"ssh -o StrictHostKeyChecking=accept-new -o ConnectTimeout=10 root@${NODE} \
'timeout 180 docker pull ${NEW_IMAGE} 2>&1'" 2>&1)
if echo "$PULL_OUTPUT" | grep -q "Downloaded\|Pulled\|up to date"; then
echo -e "${GREEN}✅ Image pulled on Proxmox host${NC}"
# Import to container's Docker
echo "Importing image to container's Docker..."
ssh -o StrictHostKeyChecking=accept-new -o ConnectTimeout=10 root@192.168.11.10 \
"ssh -o StrictHostKeyChecking=accept-new -o ConnectTimeout=10 root@${NODE} \
'docker save ${NEW_IMAGE} | pct exec ${CONTAINER_ID} -- docker load 2>&1'" 2>&1 | tail -3
echo -e "${GREEN}✅ Image imported to container${NC}"
else
echo -e "${YELLOW}⚠️ Pull from host failed, trying from container...${NC}"
# Try from container with longer timeout
PULL_OUTPUT=$(ssh -o StrictHostKeyChecking=accept-new -o ConnectTimeout=10 root@192.168.11.10 \
"ssh -o StrictHostKeyChecking=accept-new -o ConnectTimeout=10 root@${NODE} \
'timeout 180 pct exec ${CONTAINER_ID} -- docker pull ${NEW_IMAGE} 2>&1'" 2>&1 | tail -5)
if echo "$PULL_OUTPUT" | grep -q "Downloaded\|Pulled\|up to date"; then
echo -e "${GREEN}✅ Image pulled from container${NC}"
else
echo -e "${YELLOW}⚠️ Network timeout. Will try to pull during container creation.${NC}"
echo "Note: Container creation will pull image if not available"
fi
fi
# Step 4: Stop current container
echo -e "${BLUE}Step 4: Stopping current container...${NC}"
ssh -o StrictHostKeyChecking=accept-new -o ConnectTimeout=5 root@192.168.11.10 \
"ssh -o StrictHostKeyChecking=accept-new -o ConnectTimeout=5 root@${NODE} \
'pct exec ${CONTAINER_ID} -- docker stop ${DOCKER_CONTAINER} 2>&1'" 2>&1
sleep 2
# Step 5: Get volume mounts
echo -e "${BLUE}Step 5: Getting volume configuration...${NC}"
VOLUMES=$(ssh -o StrictHostKeyChecking=accept-new -o ConnectTimeout=5 root@192.168.11.10 \
"ssh -o StrictHostKeyChecking=accept-new -o ConnectTimeout=5 root@${NODE} \
'pct exec ${CONTAINER_ID} -- docker inspect ${DOCKER_CONTAINER} --format \"{{range .Mounts}}-v {{.Source}}:{{.Destination}} {{end}}\" 2>&1'" 2>&1)
echo "Volumes: $VOLUMES"
# Step 6: Remove old container
echo -e "${BLUE}Step 6: Removing old container...${NC}"
ssh -o StrictHostKeyChecking=accept-new -o ConnectTimeout=5 root@192.168.11.10 \
"ssh -o StrictHostKeyChecking=accept-new -o ConnectTimeout=5 root@${NODE} \
'pct exec ${CONTAINER_ID} -- docker rm ${DOCKER_CONTAINER} 2>&1'" 2>&1
# Step 7: Create new container with updated image
echo -e "${BLUE}Step 7: Creating new container with updated image...${NC}"
ssh -o StrictHostKeyChecking=accept-new -o ConnectTimeout=5 root@192.168.11.10 \
"ssh -o StrictHostKeyChecking=accept-new -o ConnectTimeout=5 root@${NODE} \
'pct exec ${CONTAINER_ID} -- docker run -d \
--name ${DOCKER_CONTAINER} \
--restart unless-stopped \
--network bridge \
-p 80:80 \
-p 443:443 \
-p 81:81 \
${VOLUMES} \
${NEW_IMAGE} 2>&1'" 2>&1
if [ $? -eq 0 ]; then
echo -e "${GREEN}✅ New container created${NC}"
else
echo -e "${RED}❌ Failed to create container${NC}"
echo "Restoring from backup..."
# TODO: Add restore logic if needed
exit 1
fi
# Step 8: Wait for container to start
echo -e "${BLUE}Step 8: Waiting for container to start...${NC}"
sleep 5
CONTAINER_STATUS=$(ssh -o StrictHostKeyChecking=accept-new -o ConnectTimeout=5 root@192.168.11.10 \
"ssh -o StrictHostKeyChecking=accept-new -o ConnectTimeout=5 root@${NODE} \
'pct exec ${CONTAINER_ID} -- docker ps --filter name=${DOCKER_CONTAINER} --format \"{{.Status}}\" 2>&1'" 2>&1)
if [ -n "$CONTAINER_STATUS" ]; then
echo -e "${GREEN}✅ Container is running: ${CONTAINER_STATUS}${NC}"
else
echo -e "${RED}❌ Container is not running!${NC}"
echo "Checking logs..."
ssh -o StrictHostKeyChecking=accept-new -o ConnectTimeout=5 root@192.168.11.10 \
"ssh -o StrictHostKeyChecking=accept-new -o ConnectTimeout=5 root@${NODE} \
'pct exec ${CONTAINER_ID} -- docker logs ${DOCKER_CONTAINER} --tail 30 2>&1'" 2>&1 | tail -20
exit 1
fi
# Step 9: Verify new version
echo -e "${BLUE}Step 9: Verifying new version...${NC}"
NEW_VERSION=$(ssh -o StrictHostKeyChecking=accept-new -o ConnectTimeout=5 root@192.168.11.10 \
"ssh -o StrictHostKeyChecking=accept-new -o ConnectTimeout=5 root@${NODE} \
'pct exec ${CONTAINER_ID} -- docker inspect ${DOCKER_CONTAINER} --format \"{{.Config.Image}}\" 2>&1'" 2>&1)
echo "New version: $NEW_VERSION"
if echo "$NEW_VERSION" | grep -q "2026-01-20-r2"; then
echo -e "${GREEN}✅ Successfully updated to 2026-01-20-r2${NC}"
else
echo -e "${YELLOW}⚠️ Version check inconclusive${NC}"
fi
# Step 10: Test NPMplus accessibility
echo -e "${BLUE}Step 10: Testing NPMplus accessibility...${NC}"
sleep 10 # Give NPMplus time to fully start
HTTP_167=$(curl -s -o /dev/null -w '%{http_code}' --connect-timeout 5 http://192.168.11.167:80 2>&1 || echo "000")
if [ "$HTTP_167" = "200" ] || [ "$HTTP_167" = "301" ] || [ "$HTTP_167" = "302" ] || [ "$HTTP_167" = "308" ]; then
echo -e "${GREEN}✅ NPMplus is accessible (HTTP ${HTTP_167})${NC}"
else
echo -e "${YELLOW}⚠️ NPMplus returned HTTP ${HTTP_167} (may need more time to start)${NC}"
fi
# Step 11: Test proxy functionality
echo -e "${BLUE}Step 11: Testing proxy functionality...${NC}"
PROXY_TEST=$(ssh -o StrictHostKeyChecking=accept-new -o ConnectTimeout=5 root@192.168.11.10 \
"ssh -o StrictHostKeyChecking=accept-new -o ConnectTimeout=5 root@${NODE} \
'pct exec ${CONTAINER_ID} -- curl -s -H \"Host: explorer.d-bis.org\" -o /dev/null -w \"HTTP %{http_code}\" --connect-timeout 5 http://192.168.11.140:80 2>&1'" 2>&1)
if echo "$PROXY_TEST" | grep -q "200"; then
echo -e "${GREEN}✅ Proxy functionality working (${PROXY_TEST})${NC}"
else
echo -e "${YELLOW}⚠️ Proxy test: ${PROXY_TEST}${NC}"
fi
echo ""
echo "=========================================="
echo "Update Complete!"
echo "=========================================="
echo ""
echo "Summary:"
echo " - Old version: $CURRENT_VERSION"
echo " - New version: $NEW_VERSION"
echo " - Backup: ${BACKUP_FILE}"
echo ""
echo "Next steps:"
echo " 1. Verify NPMplus dashboard: https://192.168.11.167:81"
echo " 2. Test external access: curl -I https://explorer.d-bis.org"
echo " 3. Configure Let's Encrypt certificate if needed"
echo ""