diff options
| -rw-r--r-- | web/README.md | 38 | ||||
| -rw-r--r-- | web/nginx.conf.example | 39 |
2 files changed, 58 insertions, 19 deletions
diff --git a/web/README.md b/web/README.md index 13f5f85..81346fd 100644 --- a/web/README.md +++ b/web/README.md | |||
| @@ -71,34 +71,46 @@ Cargo itself cannot produce these names: it always writes | |||
| 71 | ## nginx | 71 | ## nginx |
| 72 | 72 | ||
| 73 | `web/nginx.conf.example` is a working server block for a subdomain with an | 73 | `web/nginx.conf.example` is a working server block for a subdomain with an |
| 74 | existing certificate. On Arch-based systems: | 74 | existing certificate. Debian/Ubuntu and Arch install it the same way: |
| 75 | 75 | ||
| 76 | ```sh | 76 | ```sh |
| 77 | # Debian / Ubuntu | ||
| 78 | sudo apt install nginx php-fpm | ||
| 79 | sudo install -d -o "$USER" -g www-data -m 0755 /srv/zagan.bet | ||
| 80 | |||
| 81 | # Arch | ||
| 77 | sudo pacman -S nginx php-fpm | 82 | sudo pacman -S nginx php-fpm |
| 78 | sudo install -d -o "$USER" -g http -m 0755 /srv/zagan.bet | 83 | sudo install -d -o "$USER" -g http -m 0755 /srv/zagan.bet |
| 84 | |||
| 79 | sudo cp web/nginx.conf.example /etc/nginx/conf.d/zagan.bet.conf | 85 | sudo cp web/nginx.conf.example /etc/nginx/conf.d/zagan.bet.conf |
| 80 | # edit server_name, root and the certificate paths, then: | 86 | # edit server_name, root, socket and certificate paths, then: |
| 81 | sudo nginx -t && sudo systemctl enable --now nginx php-fpm | 87 | sudo nginx -t && sudo systemctl enable --now nginx php-fpm |
| 82 | ``` | 88 | ``` |
| 83 | 89 | ||
| 84 | The pool socket and user are Arch defaults (`http`, | 90 | The example uses Debian/Ubuntu's pool socket (`/run/php/php-fpm.sock`); Arch |
| 85 | `/run/php-fpm/php-fpm.sock`). Check them and adjust `fastcgi_pass` if your | 91 | uses `/run/php-fpm/php-fpm.sock`. Check the pool's user and socket and adjust |
| 86 | distribution differs: | 92 | `fastcgi_pass` if your distribution differs: |
| 87 | 93 | ||
| 88 | ```sh | 94 | ```sh |
| 89 | grep -E '^(user|group|listen)' /etc/php/php-fpm.d/www.conf | 95 | grep -E '^(user|group|listen)' /etc/php/*/fpm/pool.d/www.conf /etc/php-fpm.d/www.conf 2>/dev/null |
| 90 | ``` | 96 | ``` |
| 91 | 97 | ||
| 92 | `rsync` publishes files as `0755`/`0644`, so the `http` worker and the php-fpm | 98 | `rsync` publishes files as `0755`/`0644`, so the PHP worker can read them |
| 93 | pool can read them without extra group juggling. `index.php` is the only | 99 | without extra group juggling. `index.php` and `latest.php` are the only |
| 94 | script; any other `.php` request 404s instead of executing. | 100 | scripts; `releases.php` is an include, and the example returns 404 for every |
| 101 | other `.php` request instead of serving it as source. | ||
| 102 | |||
| 103 | The example sends `/latest.php` with `no-store` and the two installers with | ||
| 104 | `no-cache`, so a new release is picked up immediately without giving up the | ||
| 105 | immutable caching on `/bin/`. | ||
| 95 | 106 | ||
| 96 | PHP's opcache is enabled by default and revalidates timestamps every two | 107 | PHP's opcache is enabled by default and revalidates timestamps every two |
| 97 | seconds, so a deployed `index.php` takes effect without reloading php-fpm. If | 108 | seconds, so a deployed `index.php` or `latest.php` takes effect without |
| 98 | you ever set `opcache.validate_timestamps=0`, reload php-fpm after a deploy. | 109 | reloading php-fpm. If you ever set `opcache.validate_timestamps=0`, reload |
| 110 | php-fpm after a deploy. | ||
| 99 | 111 | ||
| 100 | The php-fpm unit on Arch uses `PrivateTmp=`, so the hash cache in `/tmp` lives | 112 | The php-fpm unit often uses `PrivateTmp=`, so the hash cache in `/tmp` lives in |
| 101 | in the service's private tmp. It still works; point `ZAGAN_HASH_CACHE` at a | 113 | the service's private tmp. It still works; point `ZAGAN_HASH_CACHE` at a |
| 102 | writable path such as `/var/cache/zagan-bet-hashes.json` if you want it to | 114 | writable path such as `/var/cache/zagan-bet-hashes.json` if you want it to |
| 103 | survive a service restart. | 115 | survive a service restart. |
| 104 | 116 | ||
diff --git a/web/nginx.conf.example b/web/nginx.conf.example index ad001d1..9fc942f 100644 --- a/web/nginx.conf.example +++ b/web/nginx.conf.example | |||
| @@ -1,11 +1,12 @@ | |||
| 1 | # zagan.bet download page — nginx + php-fpm example. | 1 | # zagan.bet download page — nginx + php-fpm example. |
| 2 | # | 2 | # |
| 3 | # Install at /etc/nginx/conf.d/zagan.bet.conf (the packaged nginx.conf includes | 3 | # Install at /etc/nginx/conf.d/zagan.bet.conf (the packaged nginx.conf includes |
| 4 | # conf.d/*.conf). Replace the server name, root and certificate paths. | 4 | # conf.d/*.conf). Replace the server name, root, socket and certificate paths. |
| 5 | # | 5 | # |
| 6 | # Only index.php is PHP; everything under /bin/ is served as static files. | 6 | # Only index.php and latest.php are PHP. Everything else under the web root is |
| 7 | # The binaries are versioned, so they can be cached forever — which means you | 7 | # static: /bin/ is immutable and versioned, while the installers are stable and |
| 8 | # must bump the version (Cargo.toml) instead of overwriting a published file. | 8 | # revalidated. Any other .php request is refused, so releases.php (an include) |
| 9 | # and stray scripts cannot be downloaded as source. | ||
| 9 | 10 | ||
| 10 | server { | 11 | server { |
| 11 | listen 80; | 12 | listen 80; |
| @@ -17,7 +18,7 @@ server { | |||
| 17 | server { | 18 | server { |
| 18 | listen 443 ssl; | 19 | listen 443 ssl; |
| 19 | listen [::]:443 ssl; | 20 | listen [::]:443 ssl; |
| 20 | http2 on; | 21 | http2 on; # nginx < 1.25.1: listen 443 ssl http2; |
| 21 | server_name dl.example.com; | 22 | server_name dl.example.com; |
| 22 | 23 | ||
| 23 | root /srv/zagan.bet; | 24 | root /srv/zagan.bet; |
| @@ -39,15 +40,41 @@ server { | |||
| 39 | # The page rescans bin/ on every request, so don't cache it. | 40 | # The page rescans bin/ on every request, so don't cache it. |
| 40 | location = /index.php { | 41 | location = /index.php { |
| 41 | include fastcgi_params; | 42 | include fastcgi_params; |
| 42 | fastcgi_pass unix:/run/php-fpm/php-fpm.sock; | 43 | # Debian/Ubuntu: /run/php/php-fpm.sock |
| 44 | # Arch: /run/php-fpm/php-fpm.sock | ||
| 45 | fastcgi_pass unix:/run/php/php-fpm.sock; | ||
| 43 | fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name; | 46 | fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name; |
| 44 | add_header Cache-Control "no-cache"; | 47 | add_header Cache-Control "no-cache"; |
| 45 | } | 48 | } |
| 46 | 49 | ||
| 50 | # The newest-version feed read by install.sh and install.ps1. | ||
| 51 | location = /latest.php { | ||
| 52 | include fastcgi_params; | ||
| 53 | fastcgi_pass unix:/run/php/php-fpm.sock; | ||
| 54 | fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name; | ||
| 55 | add_header Cache-Control "no-store"; | ||
| 56 | } | ||
| 57 | |||
| 58 | # Stable installers: always revalidate so a fix reaches the next download. | ||
| 59 | location = /install.sh { | ||
| 60 | default_type text/plain; | ||
| 61 | add_header Cache-Control "no-cache"; | ||
| 62 | } | ||
| 63 | |||
| 64 | location = /install.ps1 { | ||
| 65 | default_type text/plain; | ||
| 66 | add_header Cache-Control "no-cache"; | ||
| 67 | } | ||
| 68 | |||
| 47 | location / { | 69 | location / { |
| 48 | try_files $uri $uri/ =404; | 70 | try_files $uri $uri/ =404; |
| 49 | } | 71 | } |
| 50 | 72 | ||
| 73 | # releases.php is an include only; no other script is meant to be served. | ||
| 74 | location ~ \.php$ { | ||
| 75 | return 404; | ||
| 76 | } | ||
| 77 | |||
| 51 | # Never serve dotfiles (.gitignore, editor leftovers). | 78 | # Never serve dotfiles (.gitignore, editor leftovers). |
| 52 | location ~ /\. { | 79 | location ~ /\. { |
| 53 | deny all; | 80 | deny all; |
