Built with Chinaski

Sovereignty

Chinaski is built to run on your machine, under your control, forever, with or without the internet. The project states it in one line: self-hosted, no telemetry, no phone-home, runs air-gapped. This page explains what that means in practice: what runs on your server, what never happens after install, how to deploy somewhere with no connectivity at all, and where the honest boundaries sit.

What “self-hosted” covers

  • Every dependency is either in your operating system’s package manager (Perl, SQLite, the web server) or in the application itself. There’s no Node, no Python runtime, no container orchestration needed to keep up with someone else’s release schedule.
  • All storage is local: one SQLite file for all state, media as files on disk, static output as files your web server serves directly. Backup is a file copy (or the built-in scheduled backup).
  • The core is MIT-licensed. Planned commercial add-ons (a Pro tier) are designed to use locally signed license files, no external validation servers, deliberately air-gap compatible.

What “no phone-home” covers

After installation, Chinaski makes no network calls on its own:

  • No telemetry collects and leaves the system; there is no mechanism to send it.
  • No license validation against an external server.
  • No CDN fonts, icons, or scripts are embedded in your pages.
  • The built-in version-check feature only connects when you explicitly give it an update-manifest URL and air-gap mode is off, so even the update check ships off by default.

Anything outward-facing splits into feature you choose to enable (SMTP for email notifications, webhooks, scheduled-push backups to a cloud object store, update checking) and air-gap mode disables all of them at once.

The air-gap switch and default install

A single CHINASKI_AIRGAP=1 setting makes the server refuse every outbound connection: webhooks (form/post/publish/build) aren’t dispatched, rsync or S3 deployment doesn’t run, Cloudflare Turnstile verification is skipped and the widget is removed from login and form pages, admin email notifications aren’t sent, and update checks don’t occur. Builders also strip any snippet code that references external URLs, so nothing ships from a CDN. Fresh installs write this switch into the environment by default and tell you at install time.

Your secrets also stay on your server: the SMTP password, webhook secrets, Spaces keys and similar are stored encrypted in the local database under a key derived from your CHINASKI_SECRET environment variable; plaintext credentials are never written to disk by the app.

Installing a site with no internet at all

For machines that never touch the network:

  1. On a connected machine, build an offline bundle: it packages the application source, all CPAN module tarballs, a bundled module installer, and the install script, plus a SHA-256 checksum file beside it. Copy both to removable media.
  2. On the target machine, run the installer from the bundle. It installs Perl modules only from the bundle (“no outbound connections are made”). Only a handful of system packages (perl, make, gcc, sqlite3, image libraries) need to come from your distribution’s own cache or a pre-downloaded set; on ARM boards, fetch the image libraries explicitly or the image processor won’t compile.
  3. Optionally skip systemd entirely for single-server setups (--no-service); the env file the installer writes already contains the session secret and air-gap mode set to on.

Air-gap mode with no certificates, forever

For deployments where DNS, certificate authorities, and cloud infrastructure are simply gone, Chinaski documents a permanent mode: serve the admin interface directly over HTTP with the bundled config: no reverse proxy, no TLS certificates to acquire, renew, or expire. The “works forever” guarantee is the point.

It also handles the usual reverse-proxy dependencies correctly without one: client IP detection and rate limiting fall back to real TCP addresses (spoofed proxy headers are ignored when no proxy is in front), so lockouts and throttling work unconfigured.

What sovereignty does not mean

  • It doesn’t mean zero work: updates are still your job: a deliberate process done by hand from a manifest URL (which you can leave unset forever without any impact).
  • Connectivity features (email delivery, cloud backups, webhook integrations) need connectivity when you turn them on; they just never turn themselves on.
  • The package set comes from Debian stable; keeping it that way is an operational choice you own, like the backups.
Read this site in