chore: migrate application to gunicorn server and add deployment configuration files
This commit is contained in:
parent
f7dba1d11c
commit
b0ef319728
@ -2,18 +2,28 @@ module.exports = {
|
||||
apps: [
|
||||
{
|
||||
name: 'vsphere-backup-manager',
|
||||
script: 'gui_app.py',
|
||||
// If you are using a virtual environment (recommended), set the interpreter to:
|
||||
// interpreter: './venv/bin/python3',
|
||||
interpreter: 'python3',
|
||||
// Gunicorn as the production WSGI server
|
||||
// If using a virtualenv, replace 'gunicorn' with './venv/bin/gunicorn'
|
||||
script: 'gunicorn',
|
||||
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: './',
|
||||
instances: 1,
|
||||
autorestart: true,
|
||||
watch: false,
|
||||
max_memory_restart: '500M',
|
||||
env: {
|
||||
PORT: '5000',
|
||||
SECRET_KEY: 'vsphere-backup-production-key-change-this'
|
||||
// PORT is no longer used; gunicorn binds via --bind above
|
||||
},
|
||||
error_file: './logs/pm2_err.log',
|
||||
out_file: './logs/pm2_out.log',
|
||||
|
||||
73
nginx.conf
Normal file
73
nginx.conf
Normal 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;
|
||||
}
|
||||
@ -4,3 +4,4 @@ paramiko
|
||||
zstandard
|
||||
APScheduler>=3.10
|
||||
Flask>=2.3
|
||||
gunicorn>=21.0
|
||||
|
||||
78
setup.sh
Normal file
78
setup.sh
Normal 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 ""
|
||||
Loading…
Reference in New Issue
Block a user