Hosting control panel · Ubuntu 24.04 LTS · pre-release
The hosting control panel people switch to because everything else feels old.
KLYRN takes a fresh Ubuntu server to production hosting in one command: websites, PHP, WordPress and Node.js as first-class citizens, a security model that keeps root out of the web tier, and an interface you will not dread opening.
curl -fsSL https://get.klyrn.com | bash
Runs as root on Ubuntu 24.04 LTS, x86_64 or arm64. The bootstrap verifies the signed binary before it does anything else. Requirements and what the installer does
Where it stands. The installer, the privileged core, the web tier and the panel are built and exercised against a real Ubuntu 24.04 server. Sites, databases and migrations are the current milestones. The first signed public release has not shipped yet; leave an email and you will hear when it does.
01 Install
One command. A production server.
Eleven stages that check, apply, verify and roll back themselves. Interrupt it and it resumes.
The bootstrap script is deliberately tiny. It checks the OS and architecture, downloads the
klyrn binary for your platform, verifies its checksum and ed25519 signature, and hands over to
klyrn install. Everything from there is Go, not shell.
The installer is a state machine. Every stage can tell whether it already ran, apply itself idempotently, verify its own result against an objective post-condition, and roll back. State is saved after each transition, so an interrupted install resumes from the first unverified stage instead of starting over, and running it again on a finished server changes nothing.
preflightRoot, Ubuntu 24.04, at least 1 GB RAM and 10 GB free, ports 80, 443 and 7443 free, no conflicting panel or web server.profileRecords CPU, RAM, swap, disk type and virtualisation. Every tuned value later derives from this.os-prepareBase packages. A swap file if RAM is under 4 GB and none exists. Timezone and unattended-upgrades left alone.identityTheklyrnsystem user, directories, the per-install secret key,config.json.nginxInstalls nginx, takes ownership of its config, generates it from the profile, validates withnginx -t.phpPHP 8.3 FPM with the common extensions from the Ondřej Surý PPA; the default pool disabled.mariadbMariaDB 10.11 LTS, hardened through typed SQL, root over the Unix socket, tuned from the profile.firewallufw: deny inbound, allow the SSH port that is actually in use, 80, 443 and 7443. It never locks you out.kernelConservative sysctl limits and symlink and hardlink protections.servicessystemd units for the core and the web tier; a self-signed panel certificate until you give it a hostname.verifyEvery service answers: HTTPS on 7443, the core socket, nginx on 80, MariaDB, PHP-FPM. Prints the one-time setup URL.
innodb_buffer_pool_size = 2G: 25% of 11 GB RAM, capped for mixed PHP workload
Tuning is a pure function of the server profile. Every value carries its reason, and the panel shows it.
02 Sites
Websites, PHP, WordPress and Node.js. First-class, not bolted on.
Each site gets its own Unix user. Nothing is shared between them that does not have to be.
Static
nginx serves public/ directly. HTTPS from Let's Encrypt is automatic once DNS points at the server, renewed at two-thirds of the certificate's lifetime.
PHP
One PHP-FPM pool per site, running as that site's user, with open_basedir, private temp and session directories, and a pool size derived from the server profile. PHP 8.3 by default; 8.2 and 8.4 selectable per site.
Profiles for generic PHP, Laravel and WordPress cover what people actually use .htaccess for: front-controller routing, redirects, caching headers. Advanced users add a validated nginx snippet.
WordPress
Database and user created, wp-config.php written with fresh salts, admin user set up, permalinks and caching headers configured, wp-cron replaced by a real cron entry, file permissions normalised. One action, no shared credentials between sites.
Node.js
Each app is a systemd unit running as the account user, sandboxed with memory, CPU and task limits, proxied by nginx on a port KLYRN allocates. Deploy from an archive or a Git repository with a build step; the previous release is kept, so rollback is a symlink swap. Logs come from journald, not a second supervisor.
No Apache and no .htaccess, on purpose: Apache costs memory per worker and re-reads
.htaccess on every request. Every managed WordPress platform runs nginx, and WordPress is fine
with it.
03 Migrate
Bring your cPanel and DirectAdmin accounts with you.
Inspect the plan before anything is applied. Verify before you move DNS.
Every importer produces the same thing: a normalised, inspectable bundle of accounts, domains with their document roots and PHP versions, databases with users and grants, cron entries, certificates and DNS records. A planner turns the bundle into a plan you confirm, with conflicts named, unsupported PHP versions mapped to supported ones, and features without an equivalent flagged rather than silently dropped.
The applier runs as a job with independently retryable steps. The verifier compares file counts, sizes and checksums, and database row counts, then fetches each site on the new server so you can look at it before DNS moves. Transfers use rsync over SSH with bandwidth and I/O limits so neither server is destabilised.
- Source
- Collector
- Bundle
- Planner
- Applier
- Verifier
In progress. Import from a cPanel archive is part of V1. SSH-driven cPanel migration with low-downtime sync and DirectAdmin import follow in V1.5; Plesk in V2. Mail settings are recorded in the bundle so nothing is lost, but mail hosting itself is not part of V1.
04 Self-healing
Repairs itself, within limits it will not cross.
Bounded repairs, a circuit breaker, and a record of every attempt.
Checks run on a staggered schedule: nginx is active, its config valid and answering; every PHP-FPM version; MariaDB; the panel itself; each Node app; disk space and inodes per mount; memory and swap pressure; load; certificate expiry; time sync; the firewall.
When a check fails, the health engine applies a bounded repair: restart the unit, regenerate the nginx config from the database, re-issue a certificate, re-enable a unit that was disabled. A circuit breaker allows at most three repairs per check in thirty minutes with back-off, then marks it as needing a human. Every attempt is recorded with its reason, action, result and duration.
It never deletes data, kills customer processes or changes firewall rules.
klyrn health --events
During development a failed install run left the panel crash-looping; the engine tried three restarts, opened the circuit, and, once the cause was fixed, closed it again. The whole sequence is in the event log.
05 Security
Root never talks to the internet.
Two processes, one narrow boundary, and no operation that takes a command string.
klyrn-web handles HTTPS, sign-in, sessions and rate limits as an unprivileged user. It has no
shell, cannot open the database and cannot execute anything. klyrn-core runs as root and
exposes a closed set of typed operations over a Unix socket: create site, create database, issue
certificate. Each has its own validator and authoriser, and core re-checks who is asking against its own
records, so a compromised web tier cannot claim a role it does not have.
- Browser HTTPS :7443
- klyrn-web user klyrn Authentication, sessions, REST, live events, static UI. No root, no database, no exec, no shell.
- klyrn-core root Closed registry of typed operations, each validated and audited. State, jobs, health engine, certificates.
- nginx · php-fpm · mariadb · systemd · filesystem · ufw
06 Interface
An interface built by people who have to use one.
The list of sites is the first screen, because that is what you came for.
There is no dashboard of cards. A fixed rail, a command bar that jumps to anything, and lists that open into details. Creating a site is a domain, a type and a button; PHP version, document root and profile are one click away, not in the way.
Long operations run as jobs with step-by-step progress and a readable log, streamed live. Every list has a real empty, loading, partial and error state, and the interface never shows a number it made up. Light and dark. Inter for text, JetBrains Mono for paths and values, tabular figures for anything that refreshes.
The panel serves its own TLS on port 7443, independent of nginx, so a broken web server never locks you out of the tool you need to fix it. There are no default credentials: the setup token is printed once on the console, and the setup endpoint is disabled after the first admin exists.
07 Scope
What is in V1, and what is not.
One OS, one web server, one database engine, three application types, done properly.
V1 in progress
- Ubuntu 24.04 LTS, x86_64 and arm64
- One-command installer, resumable
- Panel with admin and customer roles
- Static, PHP, WordPress and Node.js sites
- MariaDB databases
- Automatic HTTPS and renewal
- File manager, cron, streamed logs
- Local backups and restore
- cPanel archive import
- Health engine with bounded repairs
- Signed updates with rollback
- CLI and API
V1.5 planned
- Debian 12 and 13
- PostgreSQL
- Remote encrypted backups: S3, B2, SFTP
- DirectAdmin import; SSH-driven cPanel migration
- Wildcard certificates, Cloudflare DNS automation
- Two-factor sign-in
- WordPress staging and clone
- Resellers, packages, disk quotas
- Panel on a hostname behind nginx
V2 planned
- Central platform: accounts, licenses, releases
- Fleet: multi-server inventory and delegated administration
- Plesk import
- Container runtime for isolated apps
- Mail hosting, with its own design
- AlmaLinux and Rocky
Mail is not in V1 because it is the most reputation-sensitive subsystem there is and the least differentiating; shipping it half-done would hurt your deliverability. Local authoritative DNS is not the default because DNS on the hosting box is a single point of failure; KLYRN talks to your DNS provider instead.
Get notified
Hear when the first release ships.
Pricing and the first signed release are announced together. Leave an email and you will get one message when that happens.
One email when pricing and the first release are announced. Nothing else.