Built with Chinaski

Installation

Chinaski installs to a Debian/Ubuntu server with one command, or entirely offline from a bundle. This page walks through the standard install, the offline path, how to verify what you downloaded, and how upgrades work on an installed instance.

Requirements

  • A Debian/Ubuntu server; you run the installer as root.
  • Other systems work too, but the installer’s automatic package installation assumes Debian/Ubuntu; elsewhere you install the prerequisite packages yourself (documented in the project README) before running the installer.

The one-command install

On a fresh server:

curl -fsSL https://chinaski.net/install | sudo bash -s -- 1 --repo https://github.com/bigjohncobb/chinaski

That’s it. The served installer is the current version of the project’s own install script. Replace 1 with your instance name.

What the installer does, in order, all automatic:

  1. Installs every system package and Perl dependency itself (using Debian’s packaged versions where they exist; the handful not packaged are fetched from CPAN at install time). Nothing needs compiling by hand.
  2. Creates a dedicated chinaski system user.
  3. Clones the repo and lays out the application under /var/www/chinaski<instance> with restrictive permissions.
  4. Creates and initializes the SQLite database.
  5. Generates a unique secret: printed once at the end of the install; note it somewhere safe.
  6. Registers the systemd service and the daily backup timer, both enabled.

Options:

  • --repo URL: install from a different git URL (default is the official repository).
  • --local / --src DIR: install from a local checkout instead of cloning.
  • --dir DIR: install somewhere other than /var/www/chinaski<instance>.
  • --port PORT: the listen port. Numeric instance names get 3000 + N automatically (instance 1 → 3001); non-numeric names default to 3001 unless overridden.

Rules worth knowing:

  • Instance names are alphanumeric (1, 2, prod, staging).
  • The installer refuses an existing non-empty install directory: run the uninstaller first for a reinstall.
  • At the end, the completion output prints your secret. Save it.
  • A daily backup timer is enabled automatically as part of the install; see Backup Schedule & Retention for tuning.

First run

The first visit to the site redirects to the setup screen, where you set the first administrator’s username and password (minimum 12 characters plus mixed case and a digit). After setup completes, the setup screen disappears permanently. Scripted installs can complete the same step from the command line instead (see the CLI & Server Reference).

Installing offline (no internet, ever)

On a connected machine:

bash install/make-bundle.sh

produces a release bundle plus its checksum: application source, every Perl module needed, a bundled installer: everything the target machine needs. Copy the bundle to the target over USB or any offline medium, then:

tar -xzf chinaski-<commit>.tar.gz
cd chinaski-<commit>
sudo bash install.sh

No DNS, no certificates, no downloads: all dependencies resolve from the bundle itself. The offline install pre-sets the secret and airgap mode in the env file. An online variant of the same installer exists with flags for install location (--prefix), skipping service registration (--no-service), and skipping system packages (--no-apt).

Verifying an artifact

Build outputs can be accompanied by a signed manifest: a file listing every release artifact with its cryptographic hash, signed with the project’s Ed25519 key. A bundled verifier checks it offline:

perl tools/verify-manifest.pl \
  --manifest build-manifest.json \
  --sig      build-manifest.json.sig \
  --pubkey   keys/chinaski_manifest.pub \
  --output   output/

Exit 0 means the signature is valid and every listed file matches its recorded checksum; anything else prints exactly which files differ (with --strict-tree, it also flags files present on disk but missing from the manifest). No network needed, usable on air-gapped hosts.

Updating an installed site

Updates are per-instance and deliberate:

  1. Pull the new code for that instance.
  2. Update dependencies (the script uses a bundled vendor/ directory when present, so offline servers update cleanly).
  3. Syntax-check the new code before anything is touched.
  4. Rebuild the site: if the build fails, the update aborts rather than restarting the service over broken output. (An opt-in environment flag lets a code-only hotfix through when the builder itself is wedged.)
  5. Restart the service and show the result; the web-server document root is updated automatically if your language URL mode changed.

You can run a deploy explicitly (deploy.sh <instance>), wire it behind a webhook, or let the Manager drive it. Each attempt is safe: the running site keeps serving until the new one fully checks out.

After install

  • Complete first-run setup (choose the first admin’s username/password).
  • Check the automatic backup timer ran.
  • Updates arrive via the deploy script; new installs always begin from the version the installer clones for you.
Read this site in