Built with Chinaski

Static Hosting

A built Chinaski site is a plain tree of HTML/CSS/images sharpened for static serving; the typical deployment again is a reverse proxy or a static host reading that output. This page covers serving with nginx or Caddy, how the redirect files work (Netlify-style hosting) and what routes a “static” site still needs to forward to the CMS.

The built output

One directory per language (or a single root for monolingual sites):

  • index.html per directory, with try-files semantics translating URLs to paths.
  • _redirects: the Netlify-style redirect rules the builder generates each build (slug redirects with their configured status codes).
  • _redirects.caddy: a companion file with the same redirects in Caddy’s native syntax, ready to include in a Caddyfile.
  • PWA files (sw.js, manifest, offline page) with their own cache directives.
  • Full canonical domain enforcement: a generated _redirects block that 301s the www/bare alternate host to the one matching your Site URL (see the canonical domain page for its exact syntax).

The routes a static site must still forward

Two URL families can’t be served statically and must reverse-proxy to the CMS daemon:

  • /forms/*: public form pages and submission POSTs. Without forwarding, every form submission returns 404.
  • /documents/*: document downloads (download counting, published-state gating). Without forwarding, every document URL 404s.

Both shipped examples do exactly this

The repo ships ready-made vhosts to copy and edit:

  • nginx (deploy/chinaski.nginx.example and its fuller -conf.example sibling): serves by document root, forwards /forms/ and /documents/ to 127.0.0.1:<CMS port>, sets long-cache on fonts/assets, no-cache for the service worker, short-cache on HTML, plus the app-level security headers as belt-and-braces. TLS: run certbot against the enabled vhost.
  • Caddy (deploy/chinaski.Caddyfile.example): one block per instance, proxies the loopback CMS port, sets X-Forwarded-For/Proto/Host explicitly, adds cache policies mirroring the nginx one, and routes scanner-honeypot paths (/.env, /.git/config, wp-login probes…) to the CMS so they’re logged and tarpitted instead of answered by the web server.

Loopback proxying is deliberate: proxies connecting from 127.0.0.1 are trusted by default, so no extra CHINASKI_TRUSTED_PROXIES is needed. If your proxy is a container-network hop away, add that network to CHINASKI_TRUSTED_PROXIES.

deploy.sh’s nginx root sync

On each deploy the script syncs the nginx document root against the current language mode: to output/ for monolingual sites or output/<default language> otherwise, editing only configs that reference that installation. It runs nginx -t before reload and warns, leaving safe, if the config test fails.

The redirect files

The builder emits three generated files at the output root relating to redirects. See the redirect formats page for the file-by-file breakdown, including the Caddy-specific canonical-domain line.

Netlify-style hosting

The builder writes redirect rules in the Netlify _redirects format (plain old-slug → new-slug lines with your chosen status code). Two things to know before pointing Netlify at the output:

  • Pattern redirects (* wildcards with capture placeholders) are deliberately not written into _redirects; the simple file format can’t express them safely; those live in your proxy config.
  • The generated canonical-domain block uses Caddy’s 301! force syntax in the same file. A strict Netlify redirects parser will reject that line; check/edit it before shipping the file to a non-Caddy host, or override it.

Belt-and-braces note: the security headers set by the CMS app are also present in the example vhosts, because a proxy may serve cached responses before the app gets a chance to respond.

In this section

Also in Static Hosting

Serve the built static tree with Caddy and automatic TLS: what the shipped Caddyfile example sets up and what to edit for each instance.

Serve the built static tree with nginx: the two example vhosts, proxying /forms/ and /documents/ to the CMS daemon, and the deploy-time root sync.

The redirect files each build writes at the output root, their formats for Netlify and Caddy, and the one line that only works on Caddy.

Read this site in