All documentation
  1. Home
  2. Docs
  3. Install

Install

One command on a fresh Ubuntu 24.04 LTS server. Eleven stages that each check whether they already ran, apply themselves, verify their own result, and can be rolled back.

The install command

root@ubuntu-24.04 as root
$ curl -fsSL https://get.klyrn.com | sudo bash
Installs the signed build from the beta channel; the signature is checked before anything runs.

Run it as root; sudo bash is the form that works either way, and it is what the script itself tells you to run if you are not root. On the beta channel it prints what beta means and waits for nothing: it is a notice, not a prompt. The bootstrap script is short on purpose and does four things:

  1. Checks that this is Ubuntu 24.04 on x86_64, and that you are root.
  2. Downloads the release manifest and the klyrn binary for the architecture.
  3. Verifies the binary's SHA-256 and the manifest's ed25519 signature. A mismatch stops everything before anything is written.
  4. Hands over to klyrn install. Every real step happens there, in Go, as a resumable and verifiable stage.

Three environment variables are honoured: KLYRN_CHANNEL (stable, beta, dev), KLYRN_VERSION (default latest) and KLYRN_DOWNLOAD_BASE for a mirror.

The eleven stages

State is written after every transition to /var/lib/klyrn/install/state.json, which is what makes the run resumable.

  1. preflightVerifies every requirement, and that no conflicting panel or service is present.
  2. profileCollects CPU, RAM, swap, disk type, filesystem, virtualisation and kernel. Persisted; every tuned value derives from it.
  3. os-prepareapt update, base packages (ca-certificates curl gnupg acl unzip zstd tar rsync), and a swap file if RAM is under 4 GB and none exists. Timezone and unattended-upgrades are left alone.
  4. identityCreates the klyrn system user and directories, generates the per-install secret key at /etc/klyrn/secret.key mode 0600, writes config.json.
  5. nginxInstalls nginx, takes ownership of nginx.conf generated from the profile, adds the snippets, a default catch-all server and the ACME challenge location, then runs nginx -t.
  6. phpAdds ppa:ondrej/php with a pinned key fingerprint, installs php8.3-fpm with the common extensions, sets KLYRN's global FPM defaults and disables the distribution's default pool.
  7. mariadbInstalls MariaDB 10.11 LTS, hardens it through typed SQL, writes a tuned 50-klyrn.cnf.
  8. firewallufw, default deny inbound; allows the SSH port currently in use, 80, 443 and 7443. It never locks out the port you are connected on.
  9. kernelA sysctl file with conservative network and filesystem limits from the profile, plus symlink and hardlink protections.
  10. servicessystemd units for klyrn-core (root) and klyrn-web (user klyrn), a self-signed panel certificate, enable and start.
  11. verifyEvery service active, HTTPS on 7443 answering, the core socket answering, nginx serving on 80, MariaDB accepting socket auth, PHP-FPM up. Prints the one-time setup URL.

Known failure signatures (an apt lock held, the PPA unreachable, a port in use, an interrupted dpkg) map to a diagnosis and a safe remedy: wait for the lock, dpkg --configure -a, retry with back-off. An unknown failure stops, keeps its state, and prints the exact stage and log path. On the first clean run of the test VPS (3 vCPU, 5.9 GB) all eleven stages verified in 53 seconds.

Running it again

Running the command a second time on a finished server changes nothing: every stage reports itself already done. If the previous run was interrupted, it resumes at the first stage that did not verify. If the binary on disk is newer than the one that installed the server, only the stages that depend on the binary re-apply.

This is what that looked like on the development server after a new build was pushed: identity in 53 ms, services in 263 ms, everything else skipped.

root@dev: klyrn install, with a newer binary 2 stages re-applied · 9 already done
# klyrn install

KLYRN installer 0.1.0-dev

  · Checking this server                     already done
  · Profiling hardware and deriving tuning   already done
  · Preparing the operating system           already done
   Creating KLYRN user, directories and keys 53ms
  · Installing and configuring nginx         already done
  · Installing PHP 8.3 (FPM)                 already done
  · Installing and securing MariaDB          already done
  · Configuring the firewall (ufw)           already done
  · Applying kernel network and filesystem limits already done
   Starting KLYRN services                  263ms
  · Verifying the complete installation      already done

  KLYRN is installed and verified.

  Panel:        https://51.75.165.38:7443
  Setup is already complete; sign in with your administrator account.

  CLI:          klyrn status | klyrn health | klyrn install --plan
Stage timings are the two that were recorded.
klyrn install --plan       # each stage and its state, without changing anything
klyrn install              # resume, or re-apply what a new binary needs
klyrn install --force      # re-apply stages that already verified
klyrn install --rollback   # walk completed stages back in reverse

--rollback is best effort and only touches stages that changed state. Packages stay installed; KLYRN's files, systemd units, per-site pools, per-app units and firewall rules are removed.

Where things live

/opt/klyrn/releases/<ver>/klyrn   immutable release binaries
/opt/klyrn/bin/klyrn              symlink to the current release
/opt/klyrn/runtimes/node/<ver>/   Node.js runtimes, checksum-verified
/etc/klyrn/config.json            small, human-editable
/etc/klyrn/secret.key             encryption key, mode 0600
/etc/nginx/nginx.conf             KLYRN-owned, generated from the profile
/etc/nginx/klyrn/                 generated snippets and sites
/var/lib/klyrn/klyrn.db           panel state (SQLite, root only)
/var/lib/klyrn/backups/           local backup destination
/var/log/klyrn/                   structured logs
/run/klyrn/core.sock              core RPC socket, 0660 root:klyrn
/home/<account>/sites/<domain>/public
/home/<account>/apps/<app>/
/home/<account>/logs/<domain>.{access,error}.log

An update swaps the bin/klyrn symlink between releases and keeps the previous one, which is what makes a failed update roll back automatically. See Updates.