Core Concepts
Cloady has two halves: a catalog of things you can install, and the runtime state of what you’ve actually deployed. Get the vocabulary straight and the rest of the docs read cleanly.
Workspace
A workspace is your tenancy unit — identity, members, and integrations, global
across every region. It’s the top of the tree. A workspace owns a slug
(neptolab) and lives at cloady.com/w/{slug} on the control plane.
Under the hood each workspace maps to one Kubernetes Namespace
(cloady-{slug}) per activated region, fenced by a ResourceQuota and a
LimitRange. See Resource pool model below.
Application vs Instance
These two are easy to confuse — the UI deliberately blurs them, the DB does not.
- An Application is a catalog entry — the thing you pick to install: WordPress, Postgres, your own GitHub repo. One catalog row per “thing you can install.” It appears only in the install picker.
- An Instance is a deployed copy of an Application at a specific version. This is what the dashboard calls an “Application.” Under the hood it’s an instance row plus the rendered Kubernetes workloads.
So “the WordPress in my workspace” is an instance; “WordPress” in the install picker is the catalog Application.
Each instance has a svcId — its URL slug, derived server-side from the name you
gave it (DailyFrog → dailyfrog) at create time, with a -2/-3 suffix on
collision. The svcId is immutable: to rename an instance, delete it and
recreate it.
Version, Component, Endpoint
A catalog Application is described entirely by curated docker-compose files — one per version. These three terms come straight out of that compose document:
- A Version is a specific tag of an Application — one curated
docker-compose.yml. It carries the services, volumes, exposure rules, and install-time prompts. An Application’sversions[]lists the available tags;current_versionis the install default. Each version is immutable — a new version is a new file, never an edit to a published tag. - A Component is one container the version declares — a compose
service. Its image, port, and role drive the UI preview; the compose file owns the actual container. - An Endpoint is an addressable surface of a component — a service port plus
protocol. The protocol is inferred from the port name (
http/https→ HTTP, otherwise TCP). An endpoint marked public emits an Ingress (or a raw-TCP LoadBalancer) when you expose it.
Region
A Region is one k3s cluster. Your apps run inside it. A workspace doesn’t
own a region globally — it activates a region by subscribing to a plan there.
Each instance carries the region it lives in, and the same svcId can coexist
across different regions.
hil1 is the always-on home region; other regions are provisioned on demand the
first time someone activates them.
Tier, Plan, Pool
Three related words for the billing-and-capacity layer:
- A Tier is a named bundle of pool sizes plus a base price (the flat $5 / $20 / $40 / $100 lineup). It defines how much CPU, RAM, disk, and network a workspace gets.
- A Plan is the join row for a single
(workspace, region)pair → a tier plus that region’s Stripe subscription id. A plan row existing = that region is activated for the workspace. No row, no region. There’s one Stripe subscription per workspace × region. - A Pool is the concrete resource sizing a tier grants in an activated region — the vCPU / RAM / disk / network budget your apps draw from. See below.
Environment
Every region slice is split into three environments — prod, staging, and
dev. They share the region’s pool but are isolated by svcId uniqueness:
uniqueness is (workspace, region, env, svcId), so the same app name can run in
prod and staging side by side.
Environment is a mandatory path segment in dashboard URLs:
/w/{slug}/{region}/{env}/…. prod uses the bare apex hostname; staging and
dev get an <env>. prefix on the app hostname.
Domain
A Domain is a hostname attached to an instance. Two kinds:
- Auto — a Cloady-generated
cloady.iohostname, wired up the moment you expose a public endpoint. TLS is served from a shared wildcard certificate, so there’s nothing to configure. - Custom — a hostname you supply. Point a CNAME (or A/AAAA for an apex) at your app, and Cloady issues a per-host Let’s Encrypt certificate via cert-manager automatically.
One Domain per instance is is_primary — that’s the one the dashboard’s Open
button uses.
Resource pool model
Cloady gives each workspace a VPS feel: in every activated region you get one fixed pool of vCPU, RAM, disk, and network, sized by your tier. Create as many apps as you like — each one bursts into whatever slack the pool has, instead of being boxed into a fixed per-app allocation.
This maps directly onto Kubernetes:
- The
ResourceQuotaon the workspace namespace is the pool. It caps the aggregatelimits.cpu,limits.memory,requests.storage, and pod count across every container in the workspace. - The
LimitRangeon the same namespace sets per-container defaults so you never have to think about resources: a tinydefaultRequest(so many containers fit) and a generousdefaultlimit (so any one container can burst into idle slack).
Containers run as Kubernetes QoS class Burstable — CPU is shared fairly when contended and left free when idle. A few caveats come with the VPS model:
- Memory doesn’t burst safely. If two containers peak to the pool ceiling at once, the kernel OOM-kills one. That’s natural backpressure, the same as a real VPS.
- Disk is hard-capped, not elastic. PVC storage is allocated explicitly; only
ephemeral scratch (
/tmp) shares pool slack.
URLs
Cloady uses two TLDs with distinct roles:
cloady.com— the control plane. Marketing site, dashboard, auth, status. Workspace dashboards are paths here:cloady.com/w/{slug}.cloady.io— deployment infra. Your deployed apps live here.
App hostnames follow a dashed, single-label pattern:
<component>-<svcId>-<workspaceSlug>.cloady.iocomponent— the public component’s name (e.g.wordpress)svcId— the instance’s slug (e.g.dailyfrog)workspaceSlug— the workspace slug (e.g.neptolab)
So a WordPress instance named “DailyFrog” in workspace neptolab is reachable at
wordpress-dailyfrog-neptolab.cloady.io. Non-prod environments add the env
prefix to the apex (…cloady.io → …dev.cloady.io).
The pattern is single-label deep by design: one *.cloady.io wildcard
certificate and DNS record cover every workspace and app forever. Don’t mix the
two TLDs — dashboards never live on a cloady.io subdomain, and apps never live
under a cloady.com path.
Next: see the Dashboard Guide for working in the UI, or the API Overview to drive Cloady programmatically.