# Gooneral Wheelchair - Local Deployment Preparation Script # Run this on your Windows development machine param( [Parameter(Mandatory=$true)] [string]$Domain, [Parameter(Mandatory=$false)] [string]$ServerUser = "root", [Parameter(Mandatory=$false)] [string]$ServerHost, [Parameter(Mandatory=$false)] [switch]$UploadToServer ) Write-Host "🚀 Preparing Gooneral Wheelchair for deployment..." -ForegroundColor Green Write-Host "📁 Domain: $Domain" -ForegroundColor Cyan # Generate a secure session secret $SessionSecret = [System.Web.Security.Membership]::GeneratePassword(64, 10) # Build the frontend Write-Host "🏗️ Building frontend..." -ForegroundColor Yellow npm run build if ($LASTEXITCODE -ne 0) { Write-Host "❌ Frontend build failed!" -ForegroundColor Red exit 1 } # Create deployment directory $DeployDir = ".\deployment-ready" if (Test-Path $DeployDir) { Remove-Item $DeployDir -Recurse -Force } New-Item -ItemType Directory -Path $DeployDir -Force | Out-Null Write-Host "📦 Packaging files..." -ForegroundColor Yellow # Copy built frontend Copy-Item -Path ".\dist" -Destination "$DeployDir\dist" -Recurse # Copy backend files $BackendDir = "$DeployDir\backend" New-Item -ItemType Directory -Path $BackendDir -Force | Out-Null $BackendFiles = @( "server.js", "start-production.js", "package.json", "auth.js", "themes.js" ) foreach ($file in $BackendFiles) { if (Test-Path ".\backend\$file") { Copy-Item -Path ".\backend\$file" -Destination "$BackendDir\$file" } } # Copy public directory if (Test-Path ".\public") { Copy-Item -Path ".\public" -Destination "$DeployDir\public" -Recurse } # Create production environment file with the generated secret $EnvContent = @" # Production Environment Variables - Generated $(Get-Date) # Server Configuration NODE_ENV=production PORT=3001 # IMPORTANT: This session secret was auto-generated # Keep this secret and secure! SESSION_SECRET=$SessionSecret # CORS Configuration FRONTEND_URL=https://$Domain # Database/Storage paths (relative to backend directory) POSTS_DIR=../public/posts THEMES_FILE=./themes.json SESSIONS_DIR=./sessions # Security Settings COOKIE_SECURE=true COOKIE_SAME_SITE=strict "@ $EnvContent | Out-File -FilePath "$BackendDir\.env.production" -Encoding UTF8 # Create Caddyfile with the actual domain $CaddyContent = @" # Caddy configuration for $Domain $Domain { # Enable automatic HTTPS # Caddy will automatically get and renew SSL certificates # Serve the React frontend (static files) root * dist # Try to serve static files first, then fallback to index.html for SPA routing try_files {path} /index.html # API routes - proxy to backend handle /api/* { reverse_proxy localhost:3001 } # Health check endpoint handle /health { reverse_proxy localhost:3001 } # Serve static files with proper headers header /assets/* { Cache-Control "public, max-age=31536000, immutable" } # Security headers header { # Enable HSTS Strict-Transport-Security "max-age=63072000; includeSubDomains; preload" # Prevent clickjacking X-Frame-Options "DENY" # Prevent MIME type sniffing X-Content-Type-Options "nosniff" # XSS protection X-XSS-Protection "1; mode=block" # Referrer policy Referrer-Policy "strict-origin-when-cross-origin" # Content Security Policy (adjust as needed) Content-Security-Policy "default-src 'self'; script-src 'self' 'unsafe-inline' 'unsafe-eval'; style-src 'self' 'unsafe-inline'; img-src 'self' data: https:; font-src 'self' data:;" } # Gzip compression encode gzip # Logging log { output file /var/log/caddy/gooneral-wheelchair.log format json } } "@ $CaddyContent | Out-File -FilePath "$DeployDir\Caddyfile" -Encoding UTF8 # Create systemd service file $ServiceContent = @" [Unit] Description=Gooneral Wheelchair CMS Backend After=network.target [Service] Type=simple User=gooneral WorkingDirectory=/opt/gooneral-wheelchair/backend Environment=NODE_ENV=production ExecStart=/usr/bin/node start-production.js Restart=always RestartSec=10 StandardOutput=syslog StandardError=syslog SyslogIdentifier=gooneral-wheelchair [Install] WantedBy=multi-user.target "@ $ServiceContent | Out-File -FilePath "$DeployDir\gooneral-wheelchair.service" -Encoding UTF8 # Create the server deployment script $ServerDeployScript = @" #!/bin/bash # Gooneral Wheelchair - Automated Server Deployment Script # This script will fully set up your CMS on the server set -e # Exit on any error echo "🚀 Starting automated deployment of Gooneral Wheelchair CMS..." # Check if running as root if [[ `$EUID -eq 0 ]]; then echo "❌ Please run this script as a regular user with sudo privileges, not as root" exit 1 fi # Check if required commands exist for cmd in node npm caddy systemctl; do if ! command -v `$cmd &> /dev/null; then echo "❌ Required command '`$cmd' not found. Please install it first." exit 1 fi done echo "✅ Prerequisites check passed" # Generate random password for admin user ADMIN_PASSWORD=`$(openssl rand -base64 32 | tr -d "=+/" | cut -c1-16) # Create application directory echo "📁 Setting up application directory..." sudo mkdir -p /opt/gooneral-wheelchair sudo chown `$USER:`$USER /opt/gooneral-wheelchair # Copy files echo "📦 Installing application files..." cp -r dist /opt/gooneral-wheelchair/ cp -r backend /opt/gooneral-wheelchair/ cp -r public /opt/gooneral-wheelchair/ 2>/dev/null || mkdir -p /opt/gooneral-wheelchair/public/posts # Install backend dependencies echo "📥 Installing backend dependencies..." cd /opt/gooneral-wheelchair/backend npm install --production --silent # Create required directories mkdir -p sessions mkdir -p ../public/posts # Set up system user for security echo "👤 Setting up system user..." if ! id "gooneral" &>/dev/null; then sudo useradd --system --shell /bin/false --home /opt/gooneral-wheelchair gooneral fi # Set proper ownership sudo chown -R gooneral:gooneral /opt/gooneral-wheelchair # Make start script executable chmod +x start-production.js # Install and start systemd service echo "⚙️ Setting up systemd service..." sudo cp ../gooneral-wheelchair.service /etc/systemd/system/ sudo systemctl daemon-reload sudo systemctl enable gooneral-wheelchair sudo systemctl start gooneral-wheelchair # Give the service a moment to start sleep 3 if sudo systemctl is-active --quiet gooneral-wheelchair; then echo "✅ Backend service started successfully" else echo "❌ Backend service failed to start. Checking logs..." sudo systemctl status gooneral-wheelchair exit 1 fi # Set up Caddy echo "🌐 Configuring Caddy..." sudo cp Caddyfile /etc/caddy/Caddyfile # Test Caddy configuration if sudo caddy validate --config /etc/caddy/Caddyfile; then echo "✅ Caddy configuration is valid" sudo systemctl reload caddy else echo "❌ Caddy configuration is invalid" exit 1 fi # Create admin user echo "👨‍💼 Creating admin user..." cd /opt/gooneral-wheelchair/backend node -e " const bcrypt = require('bcryptjs'); const fs = require('fs'); const path = require('path'); const username = 'admin'; const password = '`$ADMIN_PASSWORD'; const hashedPassword = bcrypt.hashSync(password, 10); const usersFile = path.join(__dirname, 'users.json'); const users = [ { id: 1, username: username, password: hashedPassword, role: 'admin' } ]; fs.writeFileSync(usersFile, JSON.stringify(users, null, 2)); console.log('Admin user created successfully'); " # Set proper ownership again after creating files sudo chown -R gooneral:gooneral /opt/gooneral-wheelchair # Final status check echo "" echo "🎉 Deployment completed successfully!" echo "" echo "==================== IMPORTANT ====================" echo "🔐 Your admin credentials:" echo " Username: admin" echo " Password: `$ADMIN_PASSWORD" echo "" echo "⚠️ SAVE THESE CREDENTIALS SECURELY!" echo "⚠️ Change the password after first login!" echo "==================== IMPORTANT ====================" echo "" echo "🌐 Your blog is now available at: https://$Domain" echo "🔧 Admin panel: https://$Domain/admin" echo "" echo "📊 Service status:" sudo systemctl status gooneral-wheelchair --no-pager echo "" sudo systemctl status caddy --no-pager echo "" echo "📝 To view logs:" echo " Backend: sudo journalctl -u gooneral-wheelchair -f" echo " Caddy: sudo journalctl -u caddy -f" echo "" echo "✅ Deployment complete!" "@ $ServerDeployScript | Out-File -FilePath "$DeployDir\deploy.sh" -Encoding UTF8 # Create a README for the deployment $ReadmeContent = @" # Gooneral Wheelchair - Deployment Package ## Quick Deployment 1. Upload this entire directory to your server 2. Run the deployment script: `./deploy.sh` 3. Access your blog at https://$Domain ## What's Included - Built frontend in `dist/` - Backend application in `backend/` - Auto-configured Caddyfile for $Domain - Systemd service configuration - Automated deployment script ## Generated Configuration - **Domain**: $Domain - **Session Secret**: Auto-generated (64 characters) - **Admin User**: Will be created automatically - **SSL**: Automatic via Caddy + Let's Encrypt ## After Deployment The script will output your admin credentials. Save them securely! Access your blog: - **Blog**: https://$Domain - **Admin**: https://$Domain/admin ## Manual Steps (if needed) If the automated script doesn't work, see DEPLOYMENT.md for manual instructions. "@ $ReadmeContent | Out-File -FilePath "$DeployDir\README.md" -Encoding UTF8 # Copy the detailed deployment guide Copy-Item -Path ".\DEPLOYMENT.md" -Destination "$DeployDir\DEPLOYMENT.md" # Create the upload script if server details provided if ($ServerHost -and $UploadToServer) { Write-Host "📤 Uploading to server..." -ForegroundColor Yellow # Create a tar.gz for easier upload (requires tar on Windows or WSL) $TarFile = "gooneral-wheelchair-deployment.tar.gz" if (Get-Command tar -ErrorAction SilentlyContinue) { tar -czf $TarFile -C $DeployDir . # Upload and deploy scp $TarFile "${ServerUser}@${ServerHost}:~/" ssh "${ServerUser}@${ServerHost}" " mkdir -p gooneral-wheelchair-deploy cd gooneral-wheelchair-deploy tar -xzf ../$TarFile chmod +x deploy.sh ./deploy.sh " Remove-Item $TarFile Write-Host "✅ Deployment completed remotely!" -ForegroundColor Green } else { Write-Host "⚠️ tar command not found. Please upload manually or install tar." -ForegroundColor Yellow } } Write-Host "" Write-Host "🎉 Deployment package ready!" -ForegroundColor Green Write-Host "📁 Location: $DeployDir" -ForegroundColor Cyan Write-Host "" Write-Host "Next steps:" -ForegroundColor Yellow Write-Host "1. Upload the '$DeployDir' folder to your server" -ForegroundColor White Write-Host "2. SSH to your server and run: ./deploy.sh" -ForegroundColor White Write-Host "3. Access your blog at https://$Domain" -ForegroundColor White Write-Host "" Write-Host "💡 Or run this again with -UploadToServer and -ServerHost flags for automatic upload" -ForegroundColor Gray # Save deployment info $DeployInfo = @{ Domain = $Domain SessionSecret = $SessionSecret DeploymentTime = Get-Date DeploymentPath = $DeployDir } $DeployInfo | ConvertTo-Json | Out-File -FilePath "$DeployDir\deployment-info.json" -Encoding UTF8 Write-Host "" Write-Host "✅ Session secret generated and saved securely in deployment package" -ForegroundColor Green Write-Host "🔐 Keep your deployment files secure - they contain sensitive configuration!" -ForegroundColor Red