# rustingface.com — the public face. # # A shop window for operators evaluating whether to run their own instance: # the catalogue, the model cards, and the app are readable by anyone. Weights # are not. That split is enforced by the service (`auth.mode = "bearer"` with # `auth.anonymous = "catalog"`), not by this file — nginx here is defence in # depth, and the two must not be allowed to disagree. # # Installed on hanzalova, whose WAN address is nh.thgttg.com. TCP :443 belongs # to the stream SNI router, so this listens on the https tier behind it. # # Public name => Let's Encrypt (external-tls.md). The mesh name rf.internal is # a separate vhost with an internal-CA cert, sharing this webroot and upstream # (reverse-proxies.md §2). server { listen 127.0.0.1:14443 ssl proxy_protocol; http2 on; server_name rustingface.com www.rustingface.com; ssl_certificate /etc/letsencrypt/live/rustingface.com/fullchain.pem; ssl_certificate_key /etc/letsencrypt/live/rustingface.com/privkey.pem; ssl_protocols TLSv1.2 TLSv1.3; root /var/www/rustingface; index index.html; absolute_redirect off; access_log /var/log/nginx/rustingface.com.access.log; error_log /var/log/nginx/rustingface.com.error.log; # A public origin gets the headers a public origin needs. The app loads # nothing cross-origin, so the policy can be tight. add_header X-Content-Type-Options "nosniff" always; add_header X-Frame-Options "DENY" always; add_header Referrer-Policy "no-referrer" always; add_header Strict-Transport-Security "max-age=31536000" always; proxy_http_version 1.1; proxy_set_header Host $host; proxy_set_header Connection ""; proxy_set_header X-Real-IP $proxy_protocol_addr; proxy_set_header X-Forwarded-For $proxy_protocol_addr; proxy_set_header X-Forwarded-Proto https; proxy_set_header Accept-Encoding $http_accept_encoding; proxy_buffering off; proxy_request_buffering off; client_max_body_size 0; proxy_connect_timeout 15s; proxy_read_timeout 300s; proxy_send_timeout 300s; # --- never public ------------------------------------------------------ # /metrics is exempt from the service's own auth so a mesh Prometheus can # scrape it without a credential. That exemption is fine on rf.internal # and unacceptable here, so the public vhost closes it explicitly rather # than relying on the service to. location = /metrics { return 404; } # --- the service ------------------------------------------------------- # Reachable, but the service answers 401 without a token. Published so a # token holder can pull from anywhere, and so an anonymous client gets a # 401 it can act on rather than a 404 that reads as "no such model". location ^~ /api/ { proxy_pass http://rustingface; } location ^~ /v1/ { proxy_pass http://rustingface; } location ~ /resolve/ { proxy_pass http://rustingface; } location = /healthz { proxy_pass http://rustingface; } # --- the app ----------------------------------------------------------- location /assets/ { gzip_static on; add_header Cache-Control "public, max-age=31536000, immutable"; } location = /index.html { add_header Cache-Control "no-cache"; } location / { try_files $uri $uri/ /index.html; } gzip on; gzip_types text/css application/javascript application/json image/svg+xml; gzip_min_length 1024; }