#!/bin/bash # Systemd Setup Script # Sets up Torrent Gateway as a systemd service set -e SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" PROJECT_ROOT="$(dirname "$SCRIPT_DIR")" INSTALL_DIR="/opt/torrent-gateway" SERVICE_USER="torrent-gateway" SERVICE_GROUP="torrent-gateway" echo "🚀 Torrent Gateway Systemd Setup" echo "=================================" # Check if running as root if [ "$EUID" -ne 0 ]; then echo "❌ This script must be run as root" echo "Please run: sudo $0" exit 1 fi # Parse command line arguments ENABLE_MONITORING=false USE_EXISTING_MONITORING=false SKIP_BUILD=false while [[ $# -gt 0 ]]; do case $1 in --with-monitoring) ENABLE_MONITORING=true shift ;; --use-existing-monitoring) USE_EXISTING_MONITORING=true shift ;; --skip-build) SKIP_BUILD=true shift ;; *) echo "Unknown option: $1" echo "Usage: $0 [--with-monitoring|--use-existing-monitoring|--skip-build]" exit 1 ;; esac done cd "$PROJECT_ROOT" # Install dependencies echo "đŸ“Ļ Installing system dependencies..." apt-get update apt-get install -y \ golang-go \ sqlite3 \ ffmpeg \ nginx \ logrotate \ curl \ jq \ bc \ ca-certificates \ gnupg \ lsb-release \ build-essential \ gcc # Create service user echo "👤 Creating service user..." if ! id "$SERVICE_USER" &>/dev/null; then useradd --system --home /nonexistent --shell /bin/false --create-home "$SERVICE_USER" usermod -a -G "$SERVICE_GROUP" "$SERVICE_USER" echo "✅ User $SERVICE_USER created" else echo "â„šī¸ User $SERVICE_USER already exists" fi # Build application (unless skipped) if [ "$SKIP_BUILD" = false ]; then echo "🔨 Building application..." # Create bin directory if it doesn't exist mkdir -p bin # Build with CGO enabled for SQLite support export CGO_ENABLED=1 go build -o bin/gateway \ -ldflags "-X main.version=$(git describe --tags --always) -X main.buildTime=$(date -u +%Y-%m-%dT%H:%M:%SZ) -s -w" \ ./cmd/gateway if [ ! -f "bin/gateway" ]; then echo "❌ Build failed" exit 1 fi echo "✅ Application built successfully" else echo "â­ī¸ Skipping build (using existing binary)" if [ ! -f "bin/gateway" ]; then echo "❌ No existing binary found at bin/gateway" exit 1 fi fi # Create installation directory echo "📁 Setting up installation directory..." mkdir -p "$INSTALL_DIR"/{bin,data,configs,logs,backups,web} mkdir -p "$INSTALL_DIR/data"/{blobs,chunks,transcoded,thumbnails,metadata} # Copy files (only if not already in install directory) if [ "$PWD" != "$INSTALL_DIR" ]; then cp bin/gateway "$INSTALL_DIR/bin/" cp -r configs/* "$INSTALL_DIR/configs/" 2>/dev/null || true cp -r internal/web "$INSTALL_DIR/" cp -r scripts "$INSTALL_DIR/" else echo "â„šī¸ Already running from install directory, skipping copy" fi # Set permissions chown -R "$SERVICE_USER:$SERVICE_GROUP" "$INSTALL_DIR" chmod +x "$INSTALL_DIR/bin/gateway" chmod +x "$INSTALL_DIR/scripts"/*.sh echo "✅ Installation directory configured" # Create systemd service file echo "âš™ī¸ Creating systemd service..." cat > /etc/systemd/system/torrent-gateway.service << 'EOF' [Unit] Description=Torrent Gateway Server After=network.target Wants=network.target [Service] Type=simple User=torrent-gateway Group=torrent-gateway WorkingDirectory=/opt/torrent-gateway ExecStart=/opt/torrent-gateway/bin/gateway Restart=always RestartSec=5 StandardOutput=journal StandardError=journal # Environment variables Environment=CONFIG_PATH=/opt/torrent-gateway/configs/config.yaml # Security settings NoNewPrivileges=true PrivateTmp=true ProtectSystem=strict ProtectHome=true ReadWritePaths=/opt/torrent-gateway/data ReadWritePaths=/opt/torrent-gateway/logs ReadWritePaths=/tmp # Resource limits LimitNOFILE=65536 MemoryMax=2G [Install] WantedBy=multi-user.target EOF # Create data directories echo "📁 Creating data directories..." mkdir -p "$INSTALL_DIR/data"/{blobs,chunks,transcoded,thumbnails,metadata} chown -R "$SERVICE_USER:$SERVICE_GROUP" "$INSTALL_DIR/data" # Setup log rotation echo "📜 Setting up log rotation..." cat > /etc/logrotate.d/torrent-gateway << 'EOF' /opt/torrent-gateway/logs/*.log { daily missingok rotate 30 compress delaycompress notifempty copytruncate su torrent-gateway torrent-gateway } EOF # Create enhanced nginx configuration echo "🌐 Configuring nginx..." cat > /etc/nginx/sites-available/torrent-gateway << 'EOF' # Rate limiting zones limit_req_zone $binary_remote_addr zone=api:10m rate=10r/s; limit_req_zone $binary_remote_addr zone=upload:10m rate=1r/s; # Upstreams upstream torrent_gateway { server 127.0.0.1:9877 max_fails=3 fail_timeout=30s; keepalive 32; } upstream prometheus { server 127.0.0.1:9090 max_fails=3 fail_timeout=30s; } upstream grafana { server 127.0.0.1:3000 max_fails=3 fail_timeout=30s; } server { listen 80; server_name _; # Large file upload support client_max_body_size 10G; client_body_timeout 300s; client_header_timeout 60s; proxy_request_buffering off; # Enhanced security headers add_header X-Content-Type-Options nosniff always; add_header X-Frame-Options SAMEORIGIN always; add_header X-XSS-Protection "1; mode=block" always; add_header Referrer-Policy "strict-origin-when-cross-origin" always; add_header Content-Security-Policy "default-src 'self' 'unsafe-inline' 'unsafe-eval' data: blob:; img-src 'self' data: https:; connect-src 'self' wss: ws:;" always; # Main application location / { limit_req zone=api burst=20 nodelay; proxy_pass http://torrent_gateway; proxy_http_version 1.1; proxy_set_header Upgrade $http_upgrade; proxy_set_header Connection 'upgrade'; 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_cache_bypass $http_upgrade; # Enhanced timeouts for large operations proxy_connect_timeout 60s; proxy_send_timeout 600s; proxy_read_timeout 600s; proxy_buffering off; } # Upload endpoints with stricter rate limiting location ~ ^/api/(upload|files) { limit_req zone=upload burst=5 nodelay; proxy_pass http://torrent_gateway; 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; # Extended timeouts for uploads proxy_connect_timeout 60s; proxy_send_timeout 1800s; # 30 minutes proxy_read_timeout 1800s; # 30 minutes proxy_buffering off; } # Prometheus endpoint (conditional) location /prometheus/ { auth_basic "Monitoring"; auth_basic_user_file /etc/nginx/.htpasswd; proxy_pass http://prometheus/; 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; } # Grafana endpoint (conditional) location /grafana/ { proxy_pass http://grafana/; 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; # WebSocket support for Grafana live features proxy_http_version 1.1; proxy_set_header Upgrade $http_upgrade; proxy_set_header Connection "upgrade"; } # Health check endpoint location /health { access_log off; proxy_pass http://torrent_gateway/api/health; proxy_set_header Host $host; } # Node exporter metrics (for existing monitoring) location /node-metrics { proxy_pass http://127.0.0.1:9100/metrics; proxy_set_header Host $host; access_log off; } # Deny access to sensitive files location ~ /\. { deny all; access_log off; log_not_found off; } # Enable gzip compression gzip on; gzip_vary on; gzip_min_length 1024; gzip_proxied any; gzip_comp_level 6; gzip_types text/plain text/css text/xml text/javascript application/json application/javascript application/xml+rss application/atom+xml image/svg+xml; } EOF # Enable nginx site ln -sf /etc/nginx/sites-available/torrent-gateway /etc/nginx/sites-enabled/ rm -f /etc/nginx/sites-enabled/default # Test nginx configuration nginx -t # Install monitoring stack if requested if [ "$ENABLE_MONITORING" = true ]; then echo "📊 Installing monitoring stack..." elif [ "$USE_EXISTING_MONITORING" = true ]; then echo "📊 Configuring for existing monitoring stack..." # Install Node Exporter for system metrics NODE_EXPORTER_VERSION="1.7.0" cd /tmp wget "https://github.com/prometheus/node_exporter/releases/download/v${NODE_EXPORTER_VERSION}/node_exporter-${NODE_EXPORTER_VERSION}.linux-amd64.tar.gz" tar -xzf "node_exporter-${NODE_EXPORTER_VERSION}.linux-amd64.tar.gz" mkdir -p /opt/node_exporter cp "node_exporter-${NODE_EXPORTER_VERSION}.linux-amd64/node_exporter" /opt/node_exporter/ # Create node_exporter systemd service cat > /etc/systemd/system/node-exporter.service << 'EOF' [Unit] Description=Node Exporter After=network.target [Service] Type=simple User=nobody Group=nogroup ExecStart=/opt/node_exporter/node_exporter --web.listen-address=:9100 Restart=always RestartSec=5 [Install] WantedBy=multi-user.target EOF systemctl daemon-reload systemctl enable node-exporter systemctl start node-exporter echo "✅ Node Exporter configured for existing monitoring" echo "" echo "📋 Integration Instructions:" echo "Add the following to your existing Prometheus configuration:" echo "" echo "scrape_configs:" echo " - job_name: 'torrent-gateway-app'" echo " static_configs:" echo " - targets: ['$(curl -s https://api.ipify.org || echo 'YOUR_SERVER_IP'):9877']" echo " metrics_path: '/metrics'" echo " scrape_interval: 30s" echo "" echo " - job_name: 'torrent-gateway-system'" echo " static_configs:" echo " - targets: ['$(curl -s https://api.ipify.org || echo 'YOUR_SERVER_IP'):9100']" echo " scrape_interval: 30s" echo "" echo "Monitoring endpoints available at:" echo " - Gateway metrics: http://$(curl -s https://api.ipify.org || echo 'YOUR_SERVER_IP'):9877/metrics" echo " - System metrics: http://$(curl -s https://api.ipify.org || echo 'YOUR_SERVER_IP'):9100/metrics" echo " - Via nginx: http://$(curl -s https://api.ipify.org || echo 'YOUR_SERVER_IP')/node-metrics" echo "" fi if [ "$ENABLE_MONITORING" = true ]; then # Install Prometheus PROMETHEUS_VERSION="2.48.0" cd /tmp wget "https://github.com/prometheus/prometheus/releases/download/v${PROMETHEUS_VERSION}/prometheus-${PROMETHEUS_VERSION}.linux-amd64.tar.gz" tar -xzf "prometheus-${PROMETHEUS_VERSION}.linux-amd64.tar.gz" # Create prometheus user first useradd --system --shell /bin/false prometheus || true mkdir -p /opt/prometheus cp "prometheus-${PROMETHEUS_VERSION}.linux-amd64/prometheus" /opt/prometheus/ cp "prometheus-${PROMETHEUS_VERSION}.linux-amd64/promtool" /opt/prometheus/ cp -r "prometheus-${PROMETHEUS_VERSION}.linux-amd64/console_libraries" /opt/prometheus/ cp -r "prometheus-${PROMETHEUS_VERSION}.linux-amd64/consoles" /opt/prometheus/ # Copy Prometheus config cp "$PROJECT_ROOT/configs/prometheus.yml" /opt/prometheus/ chown -R prometheus:prometheus /opt/prometheus # Create Prometheus systemd service cat > /etc/systemd/system/prometheus.service << 'EOF' [Unit] Description=Prometheus After=network.target [Service] Type=simple User=prometheus Group=prometheus ExecStart=/opt/prometheus/prometheus \ --config.file=/opt/prometheus/prometheus.yml \ --storage.tsdb.path=/opt/prometheus/data \ --web.console.templates=/opt/prometheus/consoles \ --web.console.libraries=/opt/prometheus/console_libraries \ --web.listen-address=0.0.0.0:9090 \ --web.external-url=http://localhost:9090/ Restart=always RestartSec=5 [Install] WantedBy=multi-user.target EOF mkdir -p /opt/prometheus/data chown -R prometheus:prometheus /opt/prometheus # Install Grafana echo "📈 Installing Grafana..." wget -q -O - https://packages.grafana.com/gpg.key | apt-key add - echo "deb https://packages.grafana.com/oss/deb stable main" | tee -a /etc/apt/sources.list.d/grafana.list apt-get update apt-get install -y grafana # Copy Grafana configs cp -r "$PROJECT_ROOT/configs/grafana"/* /etc/grafana/ 2>/dev/null || true chown -R grafana:grafana /etc/grafana/ echo "✅ Monitoring stack installed" fi # Create startup script echo "🔧 Creating startup script..." cat > "$INSTALL_DIR/scripts/start.sh" << 'EOF' #!/bin/bash # Torrent Gateway Startup Script set -e INSTALL_DIR="/opt/torrent-gateway" cd "$INSTALL_DIR" echo "🚀 Starting Torrent Gateway" # Check prerequisites echo "🔍 Checking prerequisites..." # Check FFmpeg if ! command -v ffmpeg >/dev/null 2>&1; then echo "âš ī¸ FFmpeg not found - transcoding will be disabled" echo "Install FFmpeg: apt-get install ffmpeg" else echo "✅ FFmpeg found" fi # Initialize database if needed if [ ! -f "data/metadata.db" ]; then echo "đŸ—„ī¸ Initializing database..." # Database will be created on first run fi # Run migrations echo "🔄 Running database migrations..." ./scripts/migrate.sh # Start main service echo "✅ Prerequisites checked" echo "🚀 Starting Torrent Gateway service..." systemctl start torrent-gateway systemctl enable torrent-gateway echo "✅ Torrent Gateway started and enabled" EOF chmod +x "$INSTALL_DIR/scripts/start.sh" # Create stop script cat > "$INSTALL_DIR/scripts/stop.sh" << 'EOF' #!/bin/bash echo "🛑 Stopping Torrent Gateway" systemctl stop torrent-gateway systemctl disable torrent-gateway if [ "$1" = "--stop-deps" ]; then echo "🛑 Stopping dependencies..." systemctl stop nginx systemctl stop prometheus 2>/dev/null || true systemctl stop grafana-server 2>/dev/null || true fi echo "✅ Torrent Gateway stopped" EOF chmod +x "$INSTALL_DIR/scripts/stop.sh" # Reload systemd and enable services echo "🔄 Configuring systemd services..." systemctl daemon-reload # No additional services needed # Enable nginx systemctl enable nginx # Enable monitoring if installed if [ "$ENABLE_MONITORING" = true ]; then systemctl enable prometheus systemctl enable grafana-server systemctl start prometheus systemctl start grafana-server fi # Enable and start nginx systemctl start nginx # Configure firewall (UFW) echo "đŸ”Ĩ Configuring firewall (UFW)..." if command -v ufw >/dev/null 2>&1; then # Enable UFW if not already enabled (non-interactive) ufw --force enable # Allow essential ports echo " Opening HTTP/HTTPS ports..." ufw allow 80/tcp comment "HTTP (nginx)" ufw allow 443/tcp comment "HTTPS (nginx)" echo " Opening SSH access..." ufw allow 22/tcp comment "SSH" echo " Opening BitTorrent/DHT ports..." ufw allow 9877/tcp comment "Gateway API" ufw allow 6883/udp comment "DHT node (peer discovery)" # Optional: Standard BitTorrent ports for better peer connectivity ufw allow 6881:6889/tcp comment "BitTorrent TCP" ufw allow 6881:6889/udp comment "BitTorrent UDP" # Reload firewall rules ufw --force reload echo "✅ Firewall configured successfully" echo " Active rules:" ufw status numbered | head -20 else echo "âš ī¸ UFW not found - firewall not configured" echo " Please manually open ports: 80, 443, 22, 9877/tcp, 6883/udp" fi echo "" echo "🎉 Torrent Gateway systemd setup completed!" echo "" echo "📋 Next steps:" echo "1. Edit config if needed:" echo " nano $INSTALL_DIR/configs/config.yaml" echo "" echo "2. Start the gateway:" echo " $INSTALL_DIR/scripts/start.sh" echo "" echo "3. Check status:" echo " systemctl status torrent-gateway" echo " journalctl -u torrent-gateway -f" echo "" echo "đŸ”Ĩ Firewall ports opened:" echo " 80/tcp - HTTP (nginx)" echo " 443/tcp - HTTPS (nginx)" echo " 22/tcp - SSH" echo " 9877/tcp - Gateway API" echo " 6883/udp - DHT node (CRITICAL for peer discovery)" echo " 6881-6889/tcp,udp - BitTorrent protocol" echo "" echo "4. Run health checks:" echo " $INSTALL_DIR/scripts/health_check.sh" echo "" echo "📊 Service URLs:" echo " Gateway Web UI: http://localhost/" echo " Gateway API: http://localhost/api/" echo " Admin Panel: http://localhost/admin" echo " Server Stats: http://localhost/stats" if [ "$ENABLE_MONITORING" = true ]; then echo " Prometheus: http://localhost:9090" echo " Grafana: http://localhost:3000" fi echo "" echo "🔧 Service management:" echo " Start: sudo systemctl start torrent-gateway" echo " Stop: sudo systemctl stop torrent-gateway" echo " Restart: sudo systemctl restart torrent-gateway" echo " Status: sudo systemctl status torrent-gateway" echo " Logs: sudo journalctl -u torrent-gateway -f"