#!/usr/bin/env node import fs from 'fs-extra'; import path from 'path'; import { fileURLToPath } from 'url'; import archiver from 'archiver'; const __filename = fileURLToPath(import.meta.url); const __dirname = path.dirname(__filename); const deploymentDir = path.join(__dirname, 'deployment-package'); const archivePath = path.join(__dirname, 'gooneral-wheelchair-deployment.zip'); console.log('šŸš€ Creating deployment package...\n'); async function createDeploymentPackage() { try { // Clean up previous package await fs.remove(deploymentDir); await fs.remove(archivePath); // Create deployment directory await fs.ensureDir(deploymentDir); console.log('šŸ“ Copying files...'); // Copy built frontend if (await fs.pathExists(path.join(__dirname, 'dist'))) { await fs.copy(path.join(__dirname, 'dist'), path.join(deploymentDir, 'dist')); console.log('āœ… Frontend build copied'); } else { console.log('āš ļø Frontend not built - run "npm run build" first'); } // Copy backend files const backendFiles = [ 'server.js', 'start-production.js', 'package.json', 'auth.js', 'themes.js', '.env.production' ]; const backendDir = path.join(deploymentDir, 'backend'); await fs.ensureDir(backendDir); for (const file of backendFiles) { const srcPath = path.join(__dirname, 'backend', file); const destPath = path.join(backendDir, file); if (await fs.pathExists(srcPath)) { await fs.copy(srcPath, destPath); console.log(`āœ… ${file} copied`); } else { console.log(`āš ļø ${file} not found`); } } // Copy public directory if (await fs.pathExists(path.join(__dirname, 'public'))) { await fs.copy(path.join(__dirname, 'public'), path.join(deploymentDir, 'public')); console.log('āœ… Public directory copied'); } // Copy configuration files const configFiles = [ 'Caddyfile', 'DEPLOYMENT.md' ]; for (const file of configFiles) { const srcPath = path.join(__dirname, file); const destPath = path.join(deploymentDir, file); if (await fs.pathExists(srcPath)) { await fs.copy(srcPath, destPath); console.log(`āœ… ${file} copied`); } } // Create systemd service file const systemdService = `[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 `; await fs.writeFile(path.join(deploymentDir, 'gooneral-wheelchair.service'), systemdService); console.log('āœ… Systemd service file created'); // Create deployment script const deployScript = `#!/bin/bash # Gooneral Wheelchair Deployment Script echo "šŸš€ Deploying Gooneral Wheelchair CMS..." # Check if running as root if [[ $EUID -eq 0 ]]; then echo "āŒ This script should not be run as root" exit 1 fi # Create application directory sudo mkdir -p /opt/gooneral-wheelchair sudo chown $USER:$USER /opt/gooneral-wheelchair # Copy files echo "šŸ“ Copying application files..." cp -r dist /opt/gooneral-wheelchair/ cp -r backend /opt/gooneral-wheelchair/ cp -r public /opt/gooneral-wheelchair/ cp Caddyfile /opt/gooneral-wheelchair/ # Install backend dependencies echo "šŸ“¦ Installing backend dependencies..." cd /opt/gooneral-wheelchair/backend npm install --production # Create directories mkdir -p sessions mkdir -p ../public/posts # Set up systemd service echo "āš™ļø Setting up systemd service..." sudo cp ../gooneral-wheelchair.service /etc/systemd/system/ sudo systemctl daemon-reload echo "āœ… Deployment complete!" echo "" echo "Next steps:" echo "1. Edit /opt/gooneral-wheelchair/backend/.env.production" echo "2. Update Caddyfile with your domain" echo "3. Create admin user (see DEPLOYMENT.md)" echo "4. Start services:" echo " sudo systemctl enable gooneral-wheelchair" echo " sudo systemctl start gooneral-wheelchair" echo " sudo systemctl reload caddy" `; await fs.writeFile(path.join(deploymentDir, 'deploy.sh'), deployScript); await fs.chmod(path.join(deploymentDir, 'deploy.sh'), '755'); console.log('āœ… Deployment script created'); console.log('\nšŸ“¦ Creating ZIP archive...'); // Create ZIP archive const output = fs.createWriteStream(archivePath); const archive = archiver('zip', { zlib: { level: 9 } }); archive.pipe(output); archive.directory(deploymentDir, 'gooneral-wheelchair'); await archive.finalize(); await new Promise((resolve, reject) => { output.on('close', resolve); archive.on('error', reject); }); console.log(`āœ… Deployment package created: ${path.basename(archivePath)}`); console.log(`šŸ“Š Archive size: ${(archive.pointer() / 1024 / 1024).toFixed(2)} MB`); // Clean up temporary directory await fs.remove(deploymentDir); console.log('\nšŸŽ‰ Ready for deployment!'); console.log('\nNext steps:'); console.log('1. Upload gooneral-wheelchair-deployment.zip to your server'); console.log('2. Extract: unzip gooneral-wheelchair-deployment.zip'); console.log('3. Run: cd gooneral-wheelchair && ./deploy.sh'); console.log('4. Follow the instructions in DEPLOYMENT.md'); } catch (error) { console.error('āŒ Error creating deployment package:', error); process.exit(1); } } createDeploymentPackage();