Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
28 commits
Select commit Hold shift + click to select a range
4754b97
feat: Update Features Backup & Restore
vncloudsco Oct 6, 2025
52c0c07
feat: Update Features Backup & Restore
vncloudsco Oct 6, 2025
78a4ada
feat: Enhance backup import functionality with confirmation dialog an…
vncloudsco Oct 6, 2025
3d41e98
feat: Add nginx vhost config generation during backup restore
vncloudsco Oct 6, 2025
7cc70bc
feat: Add import warning dialog and file upload functionality in Back…
vncloudsco Oct 6, 2025
188b2d6
feat: Update .gitignore to exclude documentation files and remove SSL…
vncloudsco Oct 6, 2025
b63e88c
feat: Update backup import process to include hashed passwords for us…
vncloudsco Oct 6, 2025
a3ea1cb
feat: Enhance user import functionality to upsert users and profiles …
vncloudsco Oct 6, 2025
200f13c
feat: Add slave node management features with sync capabilities
vncloudsco Oct 6, 2025
5476ea8
fix: Correct sslCertificateId to sslCertificate in collectCurrentConf…
vncloudsco Oct 6, 2025
5a25198
fix: Simplify response handling in syncConfigToNode function
vncloudsco Oct 6, 2025
cd319e5
feat: Enhance slave node registration with API key dialog and authent…
vncloudsco Oct 6, 2025
ba7171a
feat: add system configuration management for master/slave node modes
vncloudsco Oct 6, 2025
d3841de
feat: add health check endpoint for slave nodes
vncloudsco Oct 6, 2025
846fd22
feat: implement sync configuration from master for slave nodes
vncloudsco Oct 6, 2025
85cf2d9
feat: Implement node synchronization between master and slave nodes
vncloudsco Oct 6, 2025
7115724
feat: Update slave node configuration and status during API key valid…
vncloudsco Oct 6, 2025
152f4d9
feat: Add slave node status checker and integrate with application li…
vncloudsco Oct 6, 2025
f3415d3
feat: Add endpoint to get current config hash for slave nodes
vncloudsco Oct 6, 2025
d3464a7
Merge branch 'beta_developer' into features_slave
vncloudsco Oct 6, 2025
48e87ef
feat: Enhance SSRF protection with URL validation and response checks
vncloudsco Oct 6, 2025
335bf71
refactor: Rename variables for SSL certificates, ModSecurity rules, a…
vncloudsco Oct 6, 2025
29b012c
feat: Add comprehensive update script for Nginx Love UI, including se…
vncloudsco Oct 6, 2025
1b5b94f
feat: Improve update script by ensuring database container is running…
vncloudsco Oct 6, 2025
1a07007
feat: Improve update script by ensuring database container starts cor…
vncloudsco Oct 6, 2025
6cf1faa
feat: Update Prisma client generation and migration steps in the upda…
vncloudsco Oct 6, 2025
a90c75e
refactor: Remove BackupStatus, BackupSchedule, and BackupFile models …
vncloudsco Oct 6, 2025
1459dac
Merge branch 'beta_developer' into features_update
vncloudsco Oct 6, 2025
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
44 changes: 0 additions & 44 deletions apps/api/prisma/schema.prisma
Original file line number Diff line number Diff line change
Expand Up @@ -625,47 +625,3 @@ model ConfigVersion {
@@index([createdAt])
@@map("config_versions")
}

enum BackupStatus {
success
failed
running
pending
}

model BackupSchedule {
id String @id @default(cuid())
name String
schedule String // Cron expression
enabled Boolean @default(true)
lastRun DateTime?
nextRun DateTime?
status BackupStatus @default(pending)

backups BackupFile[]

createdAt DateTime @default(now())
updatedAt DateTime @updatedAt

@@map("backup_schedules")
}

model BackupFile {
id String @id @default(cuid())
scheduleId String?
schedule BackupSchedule? @relation(fields: [scheduleId], references: [id], onDelete: SetNull)

filename String
filepath String
size BigInt // Size in bytes
status BackupStatus @default(success)
type String @default("full") // full, incremental, manual

metadata Json? // Additional metadata (domains count, rules count, etc.)

createdAt DateTime @default(now())

@@index([scheduleId])
@@index([createdAt])
@@map("backup_files")
}
274 changes: 274 additions & 0 deletions scripts/update.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,274 @@
#!/bin/bash

################################################################################
# Nginx Love UI - Update Script
# Description: Update source code, rebuild and restart services
# Version: 1.0.0
################################################################################

set -e

# Colors
RED='\033[0;31m'
GREEN='\033[0;32m'
YELLOW='\033[1;33m'
BLUE='\033[0;34m'
NC='\033[0m'

# Configuration
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
PROJECT_DIR="$(cd "$SCRIPT_DIR/.." && pwd)"
BACKEND_DIR="$PROJECT_DIR/apps/api"
FRONTEND_DIR="$PROJECT_DIR/apps/web"
LOG_FILE="/var/log/nginx-love-ui-update.log"

# Database configuration
DB_CONTAINER_NAME="nginx-love-postgres"

# Logging functions
log() {
echo -e "${GREEN}[$(date '+%Y-%m-%d %H:%M:%S')]${NC} $1" | tee -a "$LOG_FILE"
}

error() {
echo -e "${RED}[ERROR]${NC} $1" | tee -a "$LOG_FILE"
exit 1
}

warn() {
echo -e "${YELLOW}[WARN]${NC} $1" | tee -a "$LOG_FILE"
}

info() {
echo -e "${BLUE}[INFO]${NC} $1" | tee -a "$LOG_FILE"
}

# Check if running as root
if [[ "${EUID}" -ne 0 ]]; then
error "This script must be run as root (use sudo)"
fi

log "=================================="
log "Nginx Love UI Update Started"
log "=================================="

# Check if services exist
if ! systemctl list-unit-files | grep -q nginx-love-backend.service; then
error "Backend service not found. Please run deploy.sh first."
fi

if ! systemctl list-unit-files | grep -q nginx-love-frontend.service; then
error "Frontend service not found. Please run deploy.sh first."
fi

# Check if database container exists
if ! docker ps -a | grep -q "${DB_CONTAINER_NAME}"; then
error "Database container '${DB_CONTAINER_NAME}' not found. Please run deploy.sh first."
fi

# Step 1: Check prerequisites
log "Step 1/6: Checking prerequisites..."

# Check Node.js
if ! command -v node &> /dev/null; then
error "Node.js not found. Please install Node.js 18+ first."
fi

# Check pnpm
if ! command -v pnpm &> /dev/null; then
error "pnpm not found. Please install pnpm first."
fi

# Check Docker
if ! command -v docker &> /dev/null; then
error "Docker not found. Please install Docker first."
fi

log "✓ Prerequisites check passed"

# Step 2: Stop services before update
log "Step 2/6: Stopping services for update..."

# Stop backend service
if systemctl is-active --quiet nginx-love-backend.service; then
systemctl stop nginx-love-backend.service
log "✓ Backend service stopped"
else
warn "Backend service was not running"
fi

# Stop frontend service
if systemctl is-active --quiet nginx-love-frontend.service; then
systemctl stop nginx-love-frontend.service
log "✓ Frontend service stopped"
else
warn "Frontend service was not running"
fi

# Step 3: Update dependencies and build backend
log "Step 3/6: Building backend..."

cd "${PROJECT_DIR}"

# Update monorepo dependencies
log "Updating monorepo dependencies..."
pnpm install >> "${LOG_FILE}" 2>&1 || error "Failed to update monorepo dependencies"

cd "${BACKEND_DIR}"

# Start database if not running
if ! docker ps | grep -q "${DB_CONTAINER_NAME}" 2>/dev/null; then
log "Starting database container..."
docker start "${DB_CONTAINER_NAME}" 2>/dev/null || warn "Could not start database container"
sleep 3
fi

# Generate Prisma client
log "Generating Prisma client..."
pnpm prisma generate >> "$LOG_FILE" 2>&1 || error "Failed to generate Prisma client"

# Run database migrations
log "Running database migrations..."
cd "${BACKEND_DIR}"
pnpm prisma migrate deploy >> "$LOG_FILE" 2>&1 || error "Failed to run migrations"

# Seed database
log "Seeding database..."
cd "${BACKEND_DIR}"
pnpm ts-node prisma/seed.ts >> "$LOG_FILE" 2>&1 || warn "Failed to seed database (this is normal if data already exists)"
Copy link

Copilot AI Oct 6, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

There's an extra space between 'pnpm' and 'ts-node' which should be removed for consistency.

Suggested change
pnpm ts-node prisma/seed.ts >> "$LOG_FILE" 2>&1 || warn "Failed to seed database (this is normal if data already exists)"
pnpm ts-node prisma/seed.ts >> "$LOG_FILE" 2>&1 || warn "Failed to seed database (this is normal if data already exists)"

Copilot uses AI. Check for mistakes.

# Build backend
log "Building backend..."
cd "${BACKEND_DIR}"
pnpm build >> "${LOG_FILE}" 2>&1 || error "Failed to build backend"

log "✓ Backend build completed"

# Step 4: Build frontend
log "Step 4/6: Building frontend..."

cd "${FRONTEND_DIR}"

# Clean previous build
if [ -d "dist" ]; then
log "Cleaning previous frontend build..."
rm -rf dist
fi

# Build frontend
log "Building frontend..."
cd "${FRONTEND_DIR}"
pnpm build >> "${LOG_FILE}" 2>&1 || error "Failed to build frontend"

# Get public IP for CSP update
PUBLIC_IP=$(curl -s ifconfig.me || curl -s icanhazip.com || curl -s ipinfo.io/ip || echo "localhost")

# Update CSP in built index.html to use public IP
log "Updating Content Security Policy with public IP: ${PUBLIC_IP}..."
sed -i "s|__API_URL__|http://${PUBLIC_IP}:3001 http://localhost:3001|g" "${FRONTEND_DIR}/dist/index.html"
sed -i "s|__WS_URL__|ws://${PUBLIC_IP}:* ws://localhost:*|g" "${FRONTEND_DIR}/dist/index.html"

log "✓ Frontend build completed"

# Step 5: Restart services
log "Step 5/6: Starting services..."

# Database should already be running from Step 3, just verify
if ! docker ps | grep -q "${DB_CONTAINER_NAME}"; then
error "Database container stopped unexpectedly. Please check Docker status."
else
log "✓ Database container is running"
fi

# Start backend service
systemctl start nginx-love-backend.service || error "Failed to start backend service"
sleep 3
if ! systemctl is-active --quiet nginx-love-backend.service; then
error "Backend service failed to start. Check logs: journalctl -u nginx-love-backend.service"
fi
log "✓ Backend service started"

# Start frontend service
systemctl start nginx-love-frontend.service || error "Failed to start frontend service"
sleep 3
if ! systemctl is-active --quiet nginx-love-frontend.service; then
error "Frontend service failed to start. Check logs: journalctl -u nginx-love-frontend.service"
fi
log "✓ Frontend service started"

# Ensure nginx is running
if ! systemctl is-active --quiet nginx; then
systemctl start nginx || error "Failed to start nginx"
fi
log "✓ Nginx is running"

# Step 6: Health check and summary
log "Step 6/6: Performing health checks..."

# Health check with retries
log "Performing health checks..."
sleep 5

# Backend health check
BACKEND_HEALTHY=false
for i in {1..10}; do
if curl -s http://localhost:3001/api/health | grep -q "success"; then
BACKEND_HEALTHY=true
break
fi
sleep 2
done

if [ "$BACKEND_HEALTHY" = true ]; then
log "✅ Backend health check: PASSED"
else
warn "⚠️ Backend health check: FAILED (check logs: tail -f /var/log/nginx-love-backend.log)"
fi

# Frontend health check
FRONTEND_HEALTHY=false
for i in {1..5}; do
if curl -s http://localhost:8080 | grep -q "<!doctype html"; then
FRONTEND_HEALTHY=true
break
fi
sleep 2
done

if [ "$FRONTEND_HEALTHY" = true ]; then
log "✅ Frontend health check: PASSED"
else
warn "⚠️ Frontend health check: FAILED (check logs: tail -f /var/log/nginx-love-frontend.log)"
fi

# Final Summary
log ""
log "=================================="
log "Update Completed Successfully!"
log "=================================="
log ""
log "📋 Updated Components:"
log " • Backend API: Rebuilt and restarted"
log " • Frontend UI: Rebuilt and restarted"
log " • Database: Migrations applied, new tables seeded"
log ""
log "🌐 Services Status:"
log " • Backend API: http://${PUBLIC_IP}:3001"
log " • Frontend UI: http://${PUBLIC_IP}:8080"
log " • Database: Running in Docker container"
log ""
log "📝 Manage Services:"
log " Backend: systemctl {start|stop|restart|status} nginx-love-backend"
log " Frontend: systemctl {start|stop|restart|status} nginx-love-frontend"
log " Database: docker {start|stop|restart} ${DB_CONTAINER_NAME}"
log ""
log "📊 View Logs:"
log " Backend: tail -f /var/log/nginx-love-backend.log"
log " Frontend: tail -f /var/log/nginx-love-frontend.log"
log " Database: docker logs -f ${DB_CONTAINER_NAME}"
log " Update: tail -f ${LOG_FILE}"
log ""
log "🔐 Access the portal at: http://${PUBLIC_IP}:8080"
log ""
log "Update log saved to: ${LOG_FILE}"
log "=================================="