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)"