Built with Chinaski

Static Hosting with nginx

nginx serves the built static tree and forwards two URL families to the CMS daemon. The repo ships two example vhosts; this page covers both and the deploy-time root sync.

The two example files

  • deploy/chinaski.nginx.example: the minimal static vhost: document root, /forms/ and /documents/ proxy blocks, cache policies, and security headers.
  • deploy/chinaski.nginx.conf.example: the fuller per-instance example (port 80 by default; add TLS via certbot --nginx -d YOUR_DOMAIN after enabling the vhost).
  • Symlink into sites-enabled/, run nginx -t, then reload (systemctl reload nginx) after configuration.

The document root

Point root at the built output:

  • /var/www/chinaski<N>/output/<lang>: for path-based multilingual (individual language vhosts; e.g. one per language site).
  • /var/www/chinaski<N>/output: for monolingual sites (the none URL mode).

The deploy script auto-corrects the nginx root for you: on every deploy, deploy.sh rewrites the root directive in any nginx config referencing that install directory to match the current language mode (only output for none; else output/<default language>), runs nginx -t, and reloads, with a warning if the config test fails so you know to review manually.

Proxy blocks you need

  • location ^~ /forms/ proxies to http://127.0.0.1:CMS_PORT, required when any form on the site publishes submissions (or renders any form at all). Without it: “every form submit returns 404”.
  • location ^~ /documents/: required when the site uses the documents feature; documents’ download tracking and publish state can’t be embedded in a static build.

Other static paths need nothing beyond try_files $uri $uri/index.html =404 (plus per-asset cache directives and security headers).

Cache headers the examples set

  • HTML: short maximum (5-minute revalidate), so published content is timely.
  • Service worker: no-cache (sw.js).
  • Fonts: 1-year immutable.
  • Other assets: 1 day.
  • Security headers, as belt-and-braces: the app sets them too; the proxy adds a layer for responses before the app gets a chance.

Loopback proxying (and why it requires no extra config)

The examples proxy from 127.0.0.1: loopback, trusted by default in the app. If your real environment proxies to the CMS from a non-loopback address (a container bridge, for example), add that network to CHINASKI_TRUSTED_PROXIES so real client IPs are logged and rate limiting works per visitor.

Read this site in