Under the hood · for developers

Kubernetes, without the YAML.

The platform you would build yourself if you had a year: immutable builds, isolated projects, a rollout that waits until your app answers, and backups we restore for real every week. You push code. We run the cluster.

  • k3s · Hetzner · Nuremberg
  • Railpack + BuildKit
  • deploys by digest
  • Postgres 18 · CloudNativePG
  • Let’s Encrypt
  • HTTP/2 · IPv6
bakkerijdevries.nl · TLS renewed for you

01 · the deploy pipeline

From push to pod.

Every deploy takes the same path, every time. No hand-built servers, no half-finished rollouts. Pick a step.

Code comes in

Every push to your branch starts a deploy through our GitHub app. You can also deploy from the dashboard, or with the CLI from your terminal or AI tool. If a deploy gets cut off halfway, it is marked failed and the live version stays.

trigger
GitHub push, dashboard or CLI
cut off halfway
failed after 45 min
live version
untouched

Railpack works out the stack

Railpack detects your language and framework, and BuildKit builds the image. Builds run on build servers, separate from the servers your apps run on.

time limit
15 min
build cache
per service, never shared
build variables
secrets, never in the image
node
20 · 22 · 24 (default)

Pinned by digest

The deploy points at the image digest, not at a tag that can move. That build never changes underneath you, so what you tested is what runs.

reference
image digest
changes after build
never
same image on promote
yes

Live only when it answers

The new version has to pass a readiness check on an HTTP path or on its TCP port. Until it does, the old version keeps serving your visitors.

check
HTTP path or TCP port
interval
every 3 s
gives up
after 5 min or a fast crash

Traffic moves over

Once the new version is ready, traffic goes to it, and the old version gets a short grace period before it stops. A version that fails to start never goes live: the previous one stays or is put back.

grace period
5 s
failed start
previous version stays
variable change
restart with the new values

The last good version, on hand

Earlier images are kept. Rolling back runs one again without rebuilding, and restores the variables that version ran with.

rebuild
none
variables
as they were then
how
one click, or npx cubli rollback

02 · one project, layer by layer

Open the hood.

No black box. Pick any part of a project to see what runs there and how it is set up. These are the real settings, not a sales diagram.

01 / 08edge

Ingress + TLS

Every request comes in through Traefik behind a Hetzner load balancer. HTTPS is the only way in, and certificates take care of themselves.

redirect
HTTP always goes to HTTPS
certificates
Let’s Encrypt via cert-manager, renewed automatically
domains
A wildcard for *.cubli.app, HTTP-01 for your own domains
protocol
HTTP/2 with zstd, brotli or gzip compression
ipv6
Visitors reach you over IPv6 too
client ip
The real visitor IP reaches your app (proxy protocol)
previews
*.cubli.app addresses get noindex
02 / 08build

Build

Push to GitHub, deploy from the dashboard or run the CLI. Railpack detects your stack and BuildKit builds the image. No Dockerfile needed.

where
On build servers, separate from where apps run
limit
15 minutes per build
cache
Kept per service, never shared between customers
secrets
Build-time variables arrive as BuildKit secrets, never stored in the image
image
Deployed by digest, so a release never changes under you
node
20, 22 or 24 (24 by default)
03 / 08runtime

Your app

Your code runs in a hardened container with memory and CPU limits from your plan. A new version only takes over when it is ready.

go live
After a readiness check: HTTP path or TCP port, every 3 s
handover
The old version keeps serving until the new one is ready
bad start
Never goes live. The previous version stays or is put back
rollback
Runs an earlier image with its variables, no rebuild
hardening
seccomp RuntimeDefault, no privilege escalation, NET_RAW dropped, no service account token
crash
Restarted by Kubernetes, and the uptime check tells you if it stays down
logs
Live from the container: the last 200 lines, up to 2,000
04 / 08data

Database

Postgres or MySQL next to your app, run for you. The connection details reach your app as variables.

postgres
Postgres 18 on CloudNativePG
wal
Archived continuously, compressed with zstd, plus a full backup every week
pitr
Back to any moment of the last 14 days. Our support team does the restore
mysql
MariaDB 11.8 via mariadb-operator
dumps
Every 6 hours (kept a day), plus daily (kept 14 days)
storage
Doubles at 70% full, within your plan
05 / 08data

File volume

Uploads and other files your app writes, like WordPress media. Backed up on their own schedule.

backup
restic via k8up, every 6 hours
method
Incremental and deduplicated
encryption
A backup repository encrypted per project
retention
The last 4, plus 14 dailies
check
Repository checked every week
storage
Doubles at 80% full, within your plan
heads-up
A mail at 90% when you reach your plan’s limit
06 / 08recovery

Backups

Stored away from the servers your app runs on, in the EU. And tested for real, because a backup you never restored is a guess.

test
Every Monday at 02:00
what
A Postgres database, a MariaDB database and an app’s files
how
Restored for real in a hidden namespace
verdict
Table and file counts compared, the team alerted on failure
first run
2 October 2026: 13 of 13 tables, 543 of 543 files
freshness
Checked every 30 minutes
07 / 08isolation

Isolation boundary

Every project gets its own Kubernetes namespace per environment, so production and staging are walled off too.

network
Default-deny policies: other projects can’t reach your services
egress
Only your own project, DNS, Cubli Mail and the public internet
blocked
Private networks and the cloud metadata endpoint
variables
Encrypted with AES-256-GCM in our database
secrets
Kubernetes secrets encrypted at rest
sign-in
Two-factor for every account: an authenticator app or a passkey
support
Support access is logged, with secrets hidden
08 / 08operations

Scheduled checks

A scheduler inside the platform runs these checks around the clock. Most of the time they find nothing. That is the point.

1 min
Uptime of every live app. Down after 3 failures in a row: you get a mail, and another when it is back
1 min
Storage growth for databases and app files
1 min
New custom domains: DNS and certificate
5 min
Servers and platform health, with alerts to the Cubli team
10 min
Interrupted deploys: marked failed after 45 min, live version stays
30 min
Backup freshness
hourly
A domain whose DNS moved, for 48 hours
daily
Domain health: site, SSL and mail records
Mon 02:00
The restore test
  • Kubernetes (k3s) on Hetzner Cloud, Nuremberg
  • Three control-plane servers, each on its own physical host
  • Your app runs apart from the build servers and our control servers

03 · data

Backups you have actually restored.

Making backups is the easy part. Knowing they come back is the part most setups skip. We restore one for real every week, and store them away from your app, in the EU.

Postgres: back to any moment

CloudNativePG · Postgres 18 · WAL archived continuously (zstd) · full backup every week

14day window
continuous WAL archiveweekly full backupNeed a moment back? Our support team restores it for you.
MySQL · MariaDB 11.8

Dumps on a schedule

A dump every 6 hours, kept for a day. Plus a daily dump, kept for 14 days.

every 6 h
kept 1 day
daily
kept 14 days
files · restic

Files every 6 hours

Uploads and other app files, incremental and deduplicated. Each project has its own encrypted repository.

kept
last 4 + 14 dailies
repository check
weekly
storage · automatic

Disks that grow themselves

Storage doubles before it fills up, always within your plan. At your plan’s limit, you get a mail at 90%.

database
doubles at 70%
app files
doubles at 80%

every Monday · 02:00

A real restore, every week.

One Postgres database, one MariaDB database and one app’s files are restored for real, in a hidden namespace. Table and file counts are compared with the original, and the team is alerted if anything is off.

Weekly restore testPassed
13 / 13database tables back
543 / 543files back
› pick a backup from the EU
› restore it in a separate environment
› compare tables and files with the original
✓ everything came back

The numbers of the first test, 2 October 2026.

04 · CLI and MCP

Your terminal and your AI, both welcome.

Deploy, read logs and roll back from the command line. Or give your AI tool the same powers through MCP, so it can ship what it just wrote.

The CLI

Runs with npx, nothing to install. Uploads the folder you are in.

Sign in once
npx cubli login
Deploy the folder you are in
npx cubli up
Or put it on staging first
npx cubli up --staging
Follow the logs
npx cubli logs
Back to the previous version
npx cubli rollback
Get the code of a project
npx cubli pull

MCP for your AI tool

Claude Code, or any tool that runs a local MCP server
claude mcp add cubli -- npx -y cubli mcp
Chat apps like claude.ai or ChatGPT: add a custom connector
https://mcp.cubli.io
you, to your AI

Put this on staging, check the logs, and promote it if it answers.

Tools your AI gets

  • deploy
  • get_logs
  • rollback
  • create_database
  • create_staging
  • promote
  • add_domain
  • search_domains
  • order_domains
  • setup_domain_mail
  • domain_health
  • add_template
  • migrate_wordpress
  • pull_code

and more, for projects, services, variables and DNS. order_domains always asks for your yes before anything is bought.

Variables and logs

Set variables in the dashboard. They are encrypted with AES-256-GCM, and a change restarts your app with the new values. Connect a database and its connection details are added for you.

Logs are live from the running container: the last 200 lines by default, up to 2,000. Build logs are kept for every deploy.

There is also an API at api.cubli.io with an OpenAPI contract.

Variables
# added for you
CUBLI_URL=https://bakery.cubli.app
DATABASE_URL=postgres://…
# your own
MAIL_FROM=hello@bakkerijdevries.nl

05 · the honest comparison

Your VPS, minus the chores.

A VPS gives you a blank server. This is everything you would build on top of it, and what Cubli already does. Tick what your VPS has today.

  • The stack

    on a VPS, youInstall and patch the web server, PHP or Node and the database.

    on CubliNo server or OS for you to manage. Railpack builds the runtime, databases run as managed services.

  • TLS

    on a VPS, youSet up certificates, renew them, hope the renewal runs.

    on CubliLet’s Encrypt certificates, requested and renewed automatically. HTTP goes to HTTPS.

  • Backups

    on a VPS, youWrite the scripts and get the copies off the server.

    on CubliFiles and MySQL every 6 hours, Postgres archived continuously. Stored away from your app, in the EU.

  • Restore testing

    on a VPS, youFind out during the incident whether it works.

    on CubliA real restore every week, with table and file counts compared.

  • Monitoring

    on a VPS, youPick a tool, write the checks, route the alerts.

    on CubliAn uptime check every minute with a mail to you, plus backup and server checks for our team.

  • Full disk at 3 a.m.

    on a VPS, youWake up, resize the volume, clean up logs.

    on CubliDatabase and file storage grow automatically, within your plan.

  • Isolation

    on a VPS, youKeep sites from reaching each other yourself.

    on CubliA network-isolated project per customer, hardened containers and limits per app.

  • Deploy pipeline

    on a VPS, youBuild CI, rollbacks and a staging setup.

    on CubliDeploy on every push, immutable builds, one-click rollback, staging that promotes the same build.

  • Point-in-time recovery

    on a VPS, youSet up WAL archiving and practise the restore.

    on CubliBuilt in for every Postgres database, with a 14-day window.

Tick what your VPS already has. On Cubli, all 9 are there on day one.

Honest box

When a VPS is the better choice.

We would rather you pick the right tool than the wrong plan.

  1. 01 · rootYou need root and any software

    Daemons, custom ports, scheduled jobs, SSH, your own Dockerfile. Cubli has no shell, no cron and no custom containers yet.

  2. 02 · raw powerYou need the most CPU per euro

    A bare server gives you more raw CPU and memory for the money. A Cubli plan gives each app its own slice.

  3. 03 · the hobbyYou enjoy running servers

    Fair. Patching, backup scripts and 3 a.m. alerts can be fun. Then you know exactly what this page saves everyone else.

06 · why

Why this is the new way to host.

  1. 01

    Declarative

    You say what should run: an app, a database, a domain. The platform makes it so, and keeps it so. A crashed container comes back on its own.

    desired state
  2. 02

    Immutable

    Every deploy runs an image pinned by its digest. What you tested on staging is exactly what goes live, and rolling back is running an earlier image.

    sha256:7c1e…a94f
  3. 03

    Isolated by default

    Default-deny networking, hardened containers and limits per app. There is nothing to switch on, because it is never off.

    default deny
  4. 04

    Tested, not hoped

    A backup you never restored is a guess. We restore one every week and compare every table and file count.

    13/13 · 543/543
  5. 05

    Works with any AI

    If Claude, Codex, Cursor or Lovable puts your code in GitHub, it deploys. With the CLI and MCP, your AI tool can deploy, read logs and roll back by itself.

    git push

the fine print, up front

What we don’t do (yet).

Better you read it here than find out on day three.

  • No shell access into your container.
  • No scheduled jobs (cron) and no separate background workers.
  • No custom Dockerfiles. Railpack builds your app.
  • No CDN or edge caching in front of your site.
  • No HTTP/3 yet. HTTP/2 is on for every site.
  • No wildcard custom domains.
  • No log history or metrics graphs. Logs are live: the last 200 lines, up to 2,000.
  • No restore button or backup download in the dashboard yet. Support restores for you.
  • One region: servers in Germany.
  • No uptime guarantee or SLA.
  • Node.js and PHP are proven. Other languages Railpack knows may work, but we haven’t proven them.

Push something. Watch it land.

7 days free on any plan, cancel any time. Delete it within the trial and you pay nothing. A project with an app and a database starts at €19 a month excl. VAT, or €15.83 paid yearly.

  • servers and data in Europe
  • Kubernetes in Germany
  • backups restore-tested weekly
  • two-factor on every account