git / moonbite-network / deploy/setup-dashboard.sh · raw

#!/usr/bin/env bash# Deploy MoonBite Dashboard (Flask) on the VPS behind nginx# Run as root on your VPSset -euo pipefailREPO_URL="https://moonbite.org/git/moonbite-network.git"APP_DIR="/opt/moonbite-dashboard"APP_USER="dashboard"PORT=8050  # internal gunicorn port; nginx proxies 80 → hereecho "=== 1/7  Install system packages ==="apt-get update -qqapt-get install -y -qq python3 python3-pip python3-venv nginx git curl > /dev/nullecho "=== 2/7  Create app user & clone repo ==="id "$APP_USER" &>/dev/null || useradd -r -s /usr/sbin/nologin -m "$APP_USER"rm -rf "$APP_DIR"git clone --depth 1 "$REPO_URL" "$APP_DIR"chown -R "$APP_USER":"$APP_USER" "$APP_DIR"echo "=== 3/7  Python venv + dependencies ==="python3 -m venv "$APP_DIR/venv""$APP_DIR/venv/bin/pip" install --quiet --upgrade pipif [ -f "$APP_DIR/requirements-web.txt" ]; then    "$APP_DIR/venv/bin/pip" install --quiet -r "$APP_DIR/requirements-web.txt"else    "$APP_DIR/venv/bin/pip" install --quiet flask gunicorn ecdsafiecho "=== 4/7  Systemd service ==="cat > /etc/systemd/system/moonbite-dashboard.service <<UNIT[Unit]Description=MoonBite Dashboard (Flask/Gunicorn)After=network.target[Service]User=$APP_USERWorkingDirectory=$APP_DIRExecStart=$APP_DIR/venv/bin/gunicorn web_app:app \    --bind 127.0.0.1:$PORT \    --workers 2 \    --threads 4 \    --worker-class gthread \    --timeout 300 \    --access-logfile - \    --error-logfile -Restart=alwaysRestartSec=5[Install]WantedBy=multi-user.targetUNITsystemctl daemon-reloadsystemctl enable moonbite-dashboardsystemctl restart moonbite-dashboardecho "=== 5/7  Nginx reverse proxy ==="cat > /etc/nginx/sites-available/moonbite-dashboard <<'NGINX'server {    listen 80;    server_name _;    location / {        proxy_pass http://127.0.0.1:8050;        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;        proxy_read_timeout 300s;    }}NGINXln -sf /etc/nginx/sites-available/moonbite-dashboard /etc/nginx/sites-enabled/rm -f /etc/nginx/sites-enabled/defaultnginx -tsystemctl restart nginxecho "=== 6/7  Firewall ==="ufw allow 80/tcp 2>/dev/null || trueecho "=== 7/7  Health check ==="sleep 3echo "--- gunicorn status ---"systemctl status moonbite-dashboard --no-pager -l || trueecho ""echo "--- gunicorn journal (last 30 lines) ---"journalctl -u moonbite-dashboard --no-pager -n 30 || trueecho ""echo "--- curl test ---"curl -sf http://127.0.0.1:$PORT/ > /dev/null && echo "OK: gunicorn responds" || echo "FAIL: gunicorn not responding"curl -sf http://127.0.0.1/ > /dev/null && echo "OK: nginx responds" || echo "FAIL: nginx not responding"echo ""echo "=== DONE ==="echo "Dashboard: http://$(curl -s ifconfig.me 2>/dev/null || echo YOUR_SERVER_IP)"