From bd40b7cd8c8d9a79193cb8cfedbb94cbe82eb19f Mon Sep 17 00:00:00 2001 From: DeNNiiInc Date: Sat, 27 Dec 2025 15:52:31 +1100 Subject: [PATCH] refactor: align deployment with proxmox template --- PROXMOX_DEPLOY_TEMPLATE.md | 211 +++++++++++++++++++++++++++++++ advanced-raid-calculator.service | 15 +++ deploy.sh | 36 ++++-- server.js | 2 +- setup-proxy.sh | 21 ++- sync-and-restart.sh | 2 +- 6 files changed, 266 insertions(+), 21 deletions(-) create mode 100644 PROXMOX_DEPLOY_TEMPLATE.md create mode 100644 advanced-raid-calculator.service diff --git a/PROXMOX_DEPLOY_TEMPLATE.md b/PROXMOX_DEPLOY_TEMPLATE.md new file mode 100644 index 0000000..5d21676 --- /dev/null +++ b/PROXMOX_DEPLOY_TEMPLATE.md @@ -0,0 +1,211 @@ +# 🚀 Proxmox Deployment Template (TurnKey Node.js) + +**Use this guide to deploy ANY Node.js application to a TurnKey Linux LXC Container.** + +--- + +## 📋 Prerequisites + +1. **Project**: A Node.js application (Express, Next.js, etc.) in a Git repository. +2. **Server**: A Proxmox TurnKey Node.js Container. +3. **Access**: Root SSH password for the container. +4. **Domain (Optional)**: If using Cloudflare Tunnel. + +--- + +## 🛠️ Step 1: Prepare Your Project + +Ensure your project is ready for production: + +1. **Port Configuration**: Ensure your app listens on a configurable port or a fixed internal port (e.g., `4001`). + ```javascript + // server.js + const PORT = process.env.PORT || 4001; + app.listen(PORT, ...); + ``` + +2. **Git Ignore**: Ensure `node_modules` and config files with secrets are ignored. + ```gitignore + node_modules/ + .env + config.json + ``` + +--- + +## 🖥️ Step 2: One-Time Server Setup + +SSH into your new container: +```bash +ssh root@ +``` + +Run these commands to prepare the environment: + +### 1. Install Essentials +```bash +apt-get update && apt-get install -y git +``` + +### 2. Prepare Directory +```bash +# Standard web directory +mkdir -p /var/www/ +cd /var/www/ + +# Clone your repo (Use Basic Auth with Token if private) +# Format: https://:@github.com//.git +git clone . + +# Install dependencies +npm install +``` + +### 3. Setup Permissions +```bash +# Give ownership to www-data (Nginx user) +chown -R www-data:www-data /var/www/ +``` + +--- + +## ⚙️ Step 3: Application Configuration + +### 1. Systemd Service +Create a service file to keep your app running. + +Create `/etc/systemd/system/.service`: +```ini +[Unit] +Description= Service +After=network.target + +[Service] +Type=simple +User=root +# OR use 'www-data' if app doesn't need root ports +# User=www-data +WorkingDirectory=/var/www/ +ExecStart=/usr/local/bin/node server.js +Restart=always +Environment=NODE_ENV=production +Environment=PORT=4001 + +[Install] +WantedBy=multi-user.target +``` + +Enable and start: +```bash +systemctl daemon-reload +systemctl enable +systemctl start +``` + +### 2. Nginx Reverse Proxy +Configure Nginx to forward port 80 to your app (Port 4001). + +Create `/etc/nginx/sites-available/`: +```nginx +server { + listen 80; + server_name _; + + root /var/www/; + index index.html; + + # Serve static files (Optional) + location / { + try_files $uri $uri/ =404; + } + + # Proxy API/Dynamic requests + location /api { + proxy_pass http://localhost:4001; + proxy_http_version 1.1; + proxy_set_header Upgrade $http_upgrade; + proxy_set_header Connection 'upgrade'; + proxy_set_header Host $host; + proxy_cache_bypass $http_upgrade; + } +} +``` + +Enable site: +```bash +# Remove defaults +rm -f /etc/nginx/sites-enabled/default +rm -f /etc/nginx/sites-enabled/nodejs + +# Link new site +ln -s /etc/nginx/sites-available/ /etc/nginx/sites-enabled/ + +# Reload +nginx -t && systemctl reload nginx +``` + +--- + +## ☁️ Step 4: Cloudflare Tunnel (Secure Access) + +Expose your app securely without opening router ports. + +### 1. Install Cloudflared +```bash +# Add Key +mkdir -p --mode=0755 /usr/share/keyrings +curl -fsSL https://pkg.cloudflare.com/cloudflare-public-v2.gpg | tee /usr/share/keyrings/cloudflare-public-v2.gpg >/dev/null + +# Add Repo +echo 'deb [signed-by=/usr/share/keyrings/cloudflare-public-v2.gpg] https://pkg.cloudflare.com/cloudflared any main' | tee /etc/apt/sources.list.d/cloudflared.list + +# Install +apt-get update && apt-get install -y cloudflared +``` + +### 2. Create Tunnel +```bash +cloudflared tunnel login +cloudflared tunnel create +# Follow on-screen instructions to map domain -> http://localhost:4001 +``` + +--- + +## 🔄 Step 5: Automated Updates (PowerShell) + +Create a script `deploy-remote.ps1` in your project root to automate updates. + +**Pre-requisite**: Create `deploy-config.json` (Add to .gitignore!): +```json +{ + "host": "", + "username": "root", + "password": "", + "remotePath": "/var/www/" +} +``` + +**Script `deploy-remote.ps1`**: +```powershell +# Reads config and updates remote server +$Config = Get-Content "deploy-config.json" | ConvertFrom-Json +$User = $Config.username; $HostName = $Config.host; $Pass = $Config.password +$RemotePath = $Config.remotePath + +# Commands to run remotely +$Cmds = " + cd $RemotePath + echo '⬇️ Pulling code...' + git pull + echo '📦 Installing deps...' + npm install + echo '🚀 Restarting service...' + systemctl restart + systemctl status --no-pager +" + +echo y | plink -ssh -t -pw $Pass "$User@$HostName" $Cmds +``` + +**Usage**: Just run `./deploy-remote.ps1` to deploy! diff --git a/advanced-raid-calculator.service b/advanced-raid-calculator.service new file mode 100644 index 0000000..3824f1b --- /dev/null +++ b/advanced-raid-calculator.service @@ -0,0 +1,15 @@ +[Unit] +Description=Advanced Raid Calculator Service +After=network.target + +[Service] +Type=simple +User=www-data +WorkingDirectory=/var/www/advanced-raid-calculator +ExecStart=/usr/bin/node server.js +Restart=always +Environment=NODE_ENV=production +Environment=PORT=4001 + +[Install] +WantedBy=multi-user.target diff --git a/deploy.sh b/deploy.sh index b0a2a5b..9336f07 100644 --- a/deploy.sh +++ b/deploy.sh @@ -3,30 +3,38 @@ # Ensure we are in the project directory cd "$(dirname "$0")" -echo "Deploying Advanced Raid Calculator..." +APP_NAME="advanced-raid-calculator" +INSTALL_DIR="/var/www/$APP_NAME" +SERVICE_NAME="$APP_NAME.service" + +echo "Deploying $APP_NAME..." + +# Ensure install directory exists (if running for the first time outside of it, though git clone usually does this) +# If we are running this script FROM the repo, we assume we are already in the right place or we are setting it up. +# This script assumes it is being run inside the destination directory /var/www/advanced-raid-calculator # Install dependencies echo "Installing dependencies..." npm install -# Restart the application using PM2 -if command -v pm2 &> /dev/null; then - echo "Restarting with PM2..." - # Check if the process is already running - if pm2 list | grep -q "raid-calculator"; then - pm2 reload raid-calculator - else - pm2 start server.js --name "raid-calculator" - fi - pm2 save +# Setup Systemd Service +echo "Configuring Systemd Service..." +if [ -f "$SERVICE_NAME" ]; then + cp "$SERVICE_NAME" "/etc/systemd/system/$SERVICE_NAME" + systemctl daemon-reload + systemctl enable "$SERVICE_NAME" + systemctl restart "$SERVICE_NAME" + echo "Service restarted." else - echo "PM2 not found. Please install PM2 globally (npm install -g pm2)." - # Fallback for testing without PM2, though PM2 is expected on the TurnKey template - # node server.js + echo "Error: $SERVICE_NAME not found!" + exit 1 fi # Run the proxy setup script chmod +x setup-proxy.sh ./setup-proxy.sh +# Fix permissions (ensure www-data owns the web dir) +chown -R www-data:www-data "$INSTALL_DIR" + echo "Deployment complete." diff --git a/server.js b/server.js index 4d4606e..a984e8a 100644 --- a/server.js +++ b/server.js @@ -1,7 +1,7 @@ const express = require('express'); const path = require('path'); const app = express(); -const PORT = process.env.PORT || 3000; +const PORT = process.env.PORT || 4001; // Serve static files from the current directory app.use(express.static(__dirname)); diff --git a/setup-proxy.sh b/setup-proxy.sh index 46df333..6051736 100644 --- a/setup-proxy.sh +++ b/setup-proxy.sh @@ -8,15 +8,25 @@ fi echo "Configuring Nginx Reverse Proxy..." +APP_NAME="advanced-raid-calculator" +PORT=4001 + # Create Nginx config for the app -cat > /etc/nginx/sites-available/app < /etc/nginx/sites-available/$APP_NAME <