chore: migrate application to gunicorn server and add deployment configuration files

This commit is contained in:
bocil kematian 2026-06-22 23:56:10 +07:00
parent f7dba1d11c
commit b0ef319728
4 changed files with 167 additions and 5 deletions

View File

@ -2,18 +2,28 @@ module.exports = {
apps: [ apps: [
{ {
name: 'vsphere-backup-manager', name: 'vsphere-backup-manager',
script: 'gui_app.py', // Gunicorn as the production WSGI server
// If you are using a virtual environment (recommended), set the interpreter to: // If using a virtualenv, replace 'gunicorn' with './venv/bin/gunicorn'
// interpreter: './venv/bin/python3', script: 'gunicorn',
interpreter: 'python3', args: [
'--workers', '4',
'--bind', '127.0.0.1:5000',
'--timeout', '300', // long timeout for backup operations
'--keep-alive', '5',
'--log-level', 'info',
'--access-logfile', './logs/gunicorn_access.log',
'--error-logfile', './logs/gunicorn_error.log',
'gui_app:app'
].join(' '),
interpreter: 'none', // gunicorn is its own executable
cwd: './', cwd: './',
instances: 1, instances: 1,
autorestart: true, autorestart: true,
watch: false, watch: false,
max_memory_restart: '500M', max_memory_restart: '500M',
env: { env: {
PORT: '5000',
SECRET_KEY: 'vsphere-backup-production-key-change-this' SECRET_KEY: 'vsphere-backup-production-key-change-this'
// PORT is no longer used; gunicorn binds via --bind above
}, },
error_file: './logs/pm2_err.log', error_file: './logs/pm2_err.log',
out_file: './logs/pm2_out.log', out_file: './logs/pm2_out.log',

73
nginx.conf Normal file
View File

@ -0,0 +1,73 @@
# ─── vSphere Backup Manager Nginx reverse proxy ────────────────────────────
#
# Place this file at: /etc/nginx/sites-available/vsphere-backup-manager
# Then enable it with: sudo ln -s /etc/nginx/sites-available/vsphere-backup-manager \
# /etc/nginx/sites-enabled/
#
# Assumes:
# - SSL cert + key are at /etc/ssl/vsphere-backup/
# - Gunicorn is running on 127.0.0.1:5000 (via PM2)
# ─────────────────────────────────────────────────────────────────────────────
# Redirect plain HTTP HTTPS
server {
listen 80;
server_name _; # catches any hostname / IP
return 301 https://$host$request_uri;
}
# Main HTTPS block
server {
listen 443 ssl;
server_name _;
# ── SSL certificate (self-signed, generated by setup.sh) ──────────────────
ssl_certificate /etc/ssl/vsphere-backup/cert.pem;
ssl_certificate_key /etc/ssl/vsphere-backup/key.pem;
# ── TLS hardening ─────────────────────────────────────────────────────────
ssl_protocols TLSv1.2 TLSv1.3;
ssl_ciphers HIGH:!aNULL:!MD5;
ssl_prefer_server_ciphers on;
ssl_session_cache shared:SSL:10m;
ssl_session_timeout 10m;
# ── Security headers ──────────────────────────────────────────────────────
add_header X-Frame-Options SAMEORIGIN;
add_header X-Content-Type-Options nosniff;
add_header X-XSS-Protection "1; mode=block";
add_header Referrer-Policy strict-origin-when-cross-origin;
# Force HTTPS for 1 year remove this line if you ever need to switch back to HTTP
add_header Strict-Transport-Security "max-age=31536000" always;
# ── Proxy to Gunicorn ─────────────────────────────────────────────────────
location / {
proxy_pass http://127.0.0.1:5000;
proxy_http_version 1.1;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
# Long timeouts backup jobs can run for hours
proxy_read_timeout 3600;
proxy_connect_timeout 60;
proxy_send_timeout 3600;
# Allow large log downloads
client_max_body_size 64M;
}
# ── Static files served directly by Nginx (faster than Python) ───────────
location /static/ {
alias /home/rizqiv2/vSphere-Backup-Manager/static/;
expires 7d;
add_header Cache-Control "public";
}
# ── Logging ───────────────────────────────────────────────────────────────
access_log /var/log/nginx/vsphere-backup-access.log;
error_log /var/log/nginx/vsphere-backup-error.log;
}

View File

@ -4,3 +4,4 @@ paramiko
zstandard zstandard
APScheduler>=3.10 APScheduler>=3.10
Flask>=2.3 Flask>=2.3
gunicorn>=21.0

78
setup.sh Normal file
View File

@ -0,0 +1,78 @@
#!/usr/bin/env bash
# =============================================================================
# setup.sh — One-time setup for vSphere Backup Manager (Nginx + Gunicorn + HTTPS)
# Run as a user with sudo privileges.
# Usage: bash setup.sh
# =============================================================================
set -e
APP_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
SSL_DIR="/etc/ssl/vsphere-backup"
NGINX_CONF="/etc/nginx/sites-available/vsphere-backup-manager"
NGINX_LINK="/etc/nginx/sites-enabled/vsphere-backup-manager"
echo ""
echo "=========================================="
echo " vSphere Backup Manager — Setup Script"
echo "=========================================="
echo ""
# ── 1. Install system packages ────────────────────────────────────────────────
echo "[1/6] Installing Nginx..."
sudo apt-get update -qq
sudo apt-get install -y nginx
# ── 2. Install Python packages ────────────────────────────────────────────────
echo "[2/6] Installing Python dependencies (including gunicorn)..."
# If you use a virtualenv, activate it first:
# source ./venv/bin/activate
pip install -r "$APP_DIR/requirements.txt"
# ── 3. Generate self-signed SSL certificate (10-year validity) ────────────────
echo "[3/6] Generating self-signed TLS certificate (10 years)..."
sudo mkdir -p "$SSL_DIR"
sudo openssl req -x509 -nodes -newkey rsa:4096 \
-days 3650 \
-keyout "$SSL_DIR/key.pem" \
-out "$SSL_DIR/cert.pem" \
-subj "/C=XX/ST=Local/L=Local/O=vSphereBackup/CN=vsphere-backup-manager" \
-addext "subjectAltName=IP:127.0.0.1,IP:$(hostname -I | awk '{print $1}')"
sudo chmod 600 "$SSL_DIR/key.pem"
sudo chmod 644 "$SSL_DIR/cert.pem"
echo " Certificate saved to: $SSL_DIR"
# ── 4. Install Nginx config ───────────────────────────────────────────────────
echo "[4/6] Installing Nginx config..."
sudo cp "$APP_DIR/nginx.conf" "$NGINX_CONF"
# Remove default site if it exists
sudo rm -f /etc/nginx/sites-enabled/default
# Create symlink to enable our site
sudo ln -sf "$NGINX_CONF" "$NGINX_LINK"
sudo nginx -t # validate config before applying
sudo systemctl enable nginx
sudo systemctl restart nginx
echo " Nginx configured and running."
# ── 5. Create logs directory ──────────────────────────────────────────────────
echo "[5/6] Creating logs directory..."
mkdir -p "$APP_DIR/logs"
# ── 6. (Re)start with PM2 ────────────────────────────────────────────────────
echo "[6/6] Starting app with PM2..."
cd "$APP_DIR"
# Stop old instance if running (ignore error if not)
pm2 delete vsphere-backup-manager 2>/dev/null || true
pm2 start ecosystem.config.js
pm2 save
echo ""
echo "=========================================="
echo " Setup complete!"
echo ""
echo " Access the app at:"
echo " https://$(hostname -I | awk '{print $1}')"
echo ""
echo " First visit: browser will warn about self-signed cert."
echo " Click: Advanced → Proceed (one-time per browser)"
echo "=========================================="
echo ""