# zagan.bet download page — nginx + php-fpm example. # # Install at /etc/nginx/conf.d/zagan.bet.conf (the packaged nginx.conf includes # conf.d/*.conf). Replace the server name, root, socket and certificate paths. # # Only index.php and latest.php are PHP. Everything else under the web root is # static: /bin/ is immutable and versioned, while the installers are stable and # revalidated. Any other .php request is refused, so releases.php (an include) # and stray scripts cannot be downloaded as source. server { listen 80; listen [::]:80; server_name dl.example.com; return 301 https://$host$request_uri; } server { listen 443 ssl; listen [::]:443 ssl; http2 on; # nginx < 1.25.1: listen 443 ssl http2; server_name dl.example.com; root /srv/zagan.bet; index index.php; ssl_certificate /etc/letsencrypt/live/dl.example.com/fullchain.pem; ssl_certificate_key /etc/letsencrypt/live/dl.example.com/privkey.pem; ssl_protocols TLSv1.2 TLSv1.3; ssl_prefer_server_ciphers off; ssl_session_cache shared:SSL:10m; ssl_session_timeout 1d; # Published binaries: static, versioned, never rewritten. location /bin/ { try_files $uri =404; add_header Cache-Control "public, max-age=31536000, immutable"; } # The browser app: static files, no framework runtime. location = /play { return 301 /play/; } location /play/ { try_files $uri $uri/ /play/index.html; add_header Cache-Control "no-cache"; add_header X-Robots-Tag "noindex, nofollow, noarchive" always; add_header X-Frame-Options "DENY" always; add_header X-Content-Type-Options "nosniff" always; } # WebSocket gateway. Keep the upgrade headers and a long read timeout: # a crash round can idle for a while between pushes. location = /ws { proxy_pass http://127.0.0.1:8890; 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-Forwarded-For $proxy_add_x_forwarded_for; proxy_read_timeout 3600s; proxy_send_timeout 3600s; } # Ask crawlers and scanners to stay out, and never index a page. location = /robots.txt { default_type text/plain; try_files $uri =404; add_header Cache-Control "public, max-age=3600"; add_header X-Robots-Tag "noindex, nofollow, noarchive" always; } # The page rescans bin/ on every request, so don't cache it. location = /index.php { include fastcgi_params; # Debian/Ubuntu: /run/php/php-fpm.sock # Arch: /run/php-fpm/php-fpm.sock fastcgi_pass unix:/run/php/php-fpm.sock; fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name; add_header Cache-Control "no-cache"; add_header X-Robots-Tag "noindex, nofollow, noarchive" always; } # The newest-version feed read by install.sh and install.ps1. location = /latest.php { include fastcgi_params; fastcgi_pass unix:/run/php/php-fpm.sock; fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name; add_header Cache-Control "no-store"; add_header X-Robots-Tag "noindex, nofollow, noarchive" always; } # Stable installers: always revalidate so a fix reaches the next download. location = /install.sh { default_type text/plain; add_header Cache-Control "no-cache"; } location = /install.ps1 { default_type text/plain; add_header Cache-Control "no-cache"; } location / { try_files $uri $uri/ =404; } # releases.php is an include only; no other script is meant to be served. location ~ \.php$ { return 404; } # Never serve dotfiles (.gitignore, editor leftovers). location ~ /\. { deny all; } }