features
The whole harbor, in one hull.
boatramp is more than a static host. The same single binary publishes sites, serves them over modern HTTP, runs code at the edge, fronts your private services, scales to a cluster, and hands you the keys to all of it — with the same commands everywhere.
Everything is pre-1.0. Where a capability's live validation is still in flight, it's marked:
live seam
beta
in progress
01 / PUBLISH
Cast off, roll back, never look down.
Atomic deploys
Every publish is an immutable, content-addressed deployment; going live is one atomic pointer flip — readers never see a half-written mix.
sync
Dedup + delta uploads
Identical bytes are stored once; re-running
sync streams only the blobs that actually changed.content-addressed
Instant rollback
Re-activate any previous deployment in a single flip — nothing to rebuild, nothing to re-upload.
rollback
History & status
Inspect the live deployment and the full history — id, age, and file count.
deployments · status
Aliases & previews
Named pointers for staging and per-branch previews, plus immutable per-deploy preview hosts.
alias
Build step + bundler
Run any build tool before publishing, or the in-process Rolldown + lightningcss bundler.
build · bundle
Dry-run & validate
Preview exactly what an upload would change, and validate routing before anything ships.
--dry-run · validate
02 / PROJECTS
Many sites, one tenant boundary.
First-class projects
A project owns many sites plus their functions and compute. A site name is unique only within its project, so two teams can each own a
blog — deploys, aliases, crons, and workflow runs stay independent.project
Tenant data isolation
Each project is the tenant a handler's row-level scope resolves to:
kv, blobstore, sql, and messaging namespaces are scoped to the owning project, so same-named resources never share a data plane.tenant
Per-project RBAC
A Cedar
Project resource with project_admin / project_publisher / project_viewer roles; a token scoped to one project is refused (403) on any other.cedar
Declarative
applyOne RON manifest declares a whole project — its sites (content + build + routing), top-level functions, and compute — reconciled to desired state in a single pass.
apply.cfg
Upsert, never prunes
apply is create-or-replace and touches only what it names, so declarative and imperative management coexist; --dry-run prints the plan and writes nothing.--dry-run
Default project = no change
Everything that predates projects lives in a reserved
default project, so an omitted --project is byte-identical to single-site boatramp — no migration of your URLs or behaviour.default
03 / SERVE
A real web server, not a bucket.
Static serving
Range requests, conditional GETs, and strong ETags — automatic, nothing to configure.
range · 304
HTTP/1.1, /2, /3
HTTP/3 over QUIC served alongside the TLS listener.
h1 · h2 · h3
Routing
Redirects, internal rewrites, reverse-proxy targets, header rules, clean URLs, and a trailing-slash policy.
routing
Conditional routing
Gate redirects and rewrites on a
when predicate (a bounded CEL subset) — language, cookie, header, or file_exists — with computed ${…} destinations and automatic Vary. Edge logic without a handler.when
SPA & error docs
SPA fallback and custom error documents, folded into the immutable deployment so they roll back with content.
spa · 404
Caching
Sensible Cache-Control + ETag defaults, with per-path immutable overrides.
cache-control
Compression
Brotli and gzip precompressed at publish; on-the-fly compression for dynamic output.
br · gzip
Netlify / CF Pages compatible
Existing
_redirects and _headers files are folded into the routing manifest on sync.migrate
04 / DOMAINS & TLS
Bring a domain; keep your certs.
Virtualhosts
Attach any number of hostnames — exact and wildcard — to a site, with canonical redirects.
domain add
Ownership verification
Prove control over a host via HTTP self-verify or a DNS-TXT record before it ever routes.
domain verify
Automatic HTTPS (ACME)
HTTP-01 certificates requested on first start, cached, and renewed before expiry — no cron, no certbot.
--tls acme
Wildcard / DNS-01
Wildcard certificates via the DNS-01 challenge, plus per-deploy preview certs.
--tls acme-dns
10 managed DNS providers
Cloudflare, Route 53, Google, Azure, DigitalOcean, Hetzner, NS1, DNSimple, OCI, and Akamai — plus a manual fallback.
auto-dns
BYO cert + transport security
Serve your own certificate, and set HSTS, CSP, and frame-options per site.
--tls custom
05 / FUNCTIONS
Everything that runs is a function.
One primitive, many doors
A function is a portable WASI 0.2 component. Reach the same component as a route handler, invoke it by name, put it on a cron, or drive it from a queue — a different door, one sandbox.
function
Invoke by name
Top-level functions carry their own version line —
function deploy / alias / rollback — and invoke sync or async: durable, idempotency-keyed, and dead-lettered on failure.function invoke
Function mesh
A site handler can call sibling functions in-process through a deny-by-default
invoke_targets allowlist — the caller's bearer is forwarded unchanged, the callee quota-admitted and depth-capped. A mesh orchestrator with no network hop.invoke_targets
Event triggers
Fire a function from a signature-verified HMAC webhook, or a blob-change event — the changed key arrives as the invocation body — via the backend's native notifications.
webhook · blob
Multi-language
Author in Rust, JavaScript (jco), or Python (componentize-py); scaffold, build, and test locally —
function init · build · test · dev.rust · js · py
Metering & quotas
Every invocation is metered and exported to Prometheus, with fail-closed rate-limit and concurrency quotas.
function usage
Workflows
Chain functions into a durable DAG — fan-out, barrier fan-in, per-step retries, and saga compensation on failure. Runs survive restarts.
workflow
Per-site SQL
A real libsql database per site — an embedded file on one node, or a sqld namespace across a cluster.
sql
Bring your own SQL live seam
Point the
sql binding at your own Postgres or MySQL (Neon, Supabase, PlanetScale) — opened by name, read-only enforceable, the URL kept in a secret. Guest code is unchanged.sql-postgres · sql-mysql
KV · blob · queue
Per-site key/value, blob store, and durable messaging bindings, granted to the function.
kv · blobstore · messaging
Streams (SSE / WebSocket)
Fan messaging topics out to connected clients over Server-Sent Events or WebSocket.
streams
Deny-by-default imports
A function receives only the capabilities the site grants; anything else is refused at activation.
imports
06 / CONTAINERS & microVMs
Heavier cargo, still one hull.
Firecracker-class microVMs
Run an OCI image in a hardware-isolated VM with its own kernel, via an embedded rust-vmm VMM.
--isolation untrusted
Native OCI containers
Shared-kernel containers (namespaces, cgroups, seccomp) for code you trust.
--isolation trusted
Remote Docker
Run workloads against a remote Docker host — the compute path on macOS and Windows.
remote-docker
Scale-to-zero in progress
Snapshot an idle microVM and restore it — resuming, not rebooting — on the next request. Snapshot/restore is validated live; the automatic idle→snapshot reconcile is still being finished.
--scale-to-zero
Verified boot + posture
A signed first-party kernel is verified before boot; strict posture forces microVM isolation for untrusted code.
security explain
Cloudflare Containers beta
The same binary running as a Cloudflare cluster, with R2 for blobs and D1 for the SQL binding. Live cloud deploy/scale is a beta seam.
cloudflare
07 / GATEWAY
Front your private services.
Reverse-proxy pools
Route paths to a pool of backends — a compute workload, a server pool, or a private service.
gateway route add
Load balancing
Round-robin (default) or random across the backend pool.
--lb
Geo dispatch live seam
Route each request to the nearest healthy backend by region (
--lb nearest) — compute-backed pools auto-tag replicas by their node's region, so there's no manual map.--lb nearest
Health checks
Passive ejection after consecutive failures, plus active path probing with a cooldown.
--probe-path
Retries
Retry a body-less request against another backend on a connect failure.
--retries
DNS discovery
Resolve the pool from an A/AAAA record set instead of listing backends by hand.
--discover-host
Request rewriting
Override the upstream Host header, strip a path prefix, and set per-route timeouts.
--strip-prefix
08 / SCALE
One node to a fleet, same commands.
Single node
Filesystem blobs + an embedded SlateDB KV store. Nothing else to run.
serve
Shared-store frontends
Many stateless serving processes over one shared KV, kept coherent by a changelog — scales reads without consensus.
shared-cache
Raft cluster (HA) live seam
An openraft-replicated control plane: voters form quorum in one region, learners serve local reads elsewhere. In-process complete; live multi-host operation is the remaining seam.
ha · raft
Dynamic join
Grow a cluster with a one-paste join ticket (
cluster add → serve --cluster-join) — no static peer map; ids derive from each node's mesh key.cluster add
Kubernetes operator live seam
The in-binary operator reconciles a
BoatRampCluster CRD into a StatefulSet or Deployment + HPA, with GitOps Site and quorum-safe rolling upgrades.operator
Database per site
A real libsql database per site — a file on one node, or a sqld namespace across the cluster.
sqld
Cluster certificates
The leader issues each cert once and commits it to the log; every node replicates and hot-swaps on renewal.
cert-status
Root-key rotation
Rotate the cluster root key make-before-break: both anchors stay trusted during the overlap, so no node ever rejects a valid token — and no per-node edit.
auth rotate-root
09 / SECURE
Own the controls.
COSE/CWT tokens
Signed control-plane tokens verified offline with a public key — no per-request database lookup.
token create
Cedar RBAC
Roles map to rights (read / write / deploy / admin) per resource, via a replaceable Cedar policy.
cedar
OIDC login
Exchange an IdP JWT — Okta, Keycloak, Auth0, Entra ID — for a short-TTL boatramp token.
oidc
External signers live seam
Keep the signing key in HashiCorp Vault, a PKCS#11 HSM, or AWS / GCP / Azure KMS. Each specific service has a live seam.
signer
Offline delegation
Attenuate a token — one site, read-only, shorter expiry — by signing a restrict-only block, no server round-trip.
cnf
PoP-bound tokens (DPoP)
Bind a token to a holder key with
token create --pop: a leaked token is inert without the separately-held key, and every request signs a fresh, short-lived proof.token --pop
Day-zero control plane
Reach the control plane from the first second over raw-public-key TLS (
--tls rpk) — encrypted and pinned before any CA-signed certificate exists.--tls rpk
Visitor access control
Basic auth, IP allow/deny, rate limiting, and a WAF stage — per site, applied before any content is read.
access
Postures & secrets-at-rest
Operator-only security postures (multi-tenant / single-tenant / dev), and envelope-encrypted certificate keys.
security explain
10 / STORAGE
Your bytes, your backend.
Content-addressed blobs
Every file is a SHA-256 blob, stored once and streamed end-to-end — never held whole in memory.
blobs
Filesystem or S3
Local disk, or any S3-compatible object store — AWS, Cloudflare R2, or MinIO.
--blobs s3
Cloud object stores live seam
Google Cloud Storage (
--blobs gcs) and Azure Blob (--blobs azure), streaming, with change-notification pipelines (GCS→Pub/Sub, Azure→Event Grid) that drive blob triggers.gcs · azure
Metadata KV
Embedded SlateDB (an LSM over disk / S3 / R2 / GCS), in-memory, or Cloudflare KV.
--kv slatedb
Write-through cache
Hot metadata is fronted by an LRU cache, kept coherent across processes by the shared store.
cached-kv
11 / OPERATE
See everything, fix anything.
Prometheus metrics
Requests, response bytes, deployments, activations, and cert renewals at
/api/metrics./api/metrics
Structured logs
JSON access logs, plus per-site guest stdout/stderr with live tailing.
logs --follow
Handler stats & DLQ
Invocations, errors, consumer lag, and dead-letters — redrive or purge a stuck topic.
stats · dlq
Health endpoints
Liveness and a readiness probe that fails when the metadata backend is unreachable.
/healthz · /readyz
Backup & integrity
Snapshot each backend, and re-hash every stored blob to confirm it still matches its key.
scrub
Online store migrations
A versioned registry of forward-only store migrations the engine walks by a monotonic schema version — online, idempotent, and resumable (copy-before-delete), by hand with
migrate or automatically via serve --auto-migrate.migrate
GC + dynamic config
Prune orphaned deployments and blobs; change operational knobs fleet-wide with no restart.
prune · config
12 / SHIP
One hull, every port.
Single static binary
Server + publishing API + CLI in one file; every heavy backend lives behind a compile-time feature.
1 file
Prebuilt everywhere
Linux (x86_64 + arm64), macOS, and Windows binaries, an install script, and a Homebrew tap.
install.sh
OCI image
A multi-arch, non-root container image at
ghcr.io/boatramp/boatramp.docker
NixOS + systemd
A flake, an overlay, and a declarative
services.boatramp module with a hardened systemd unit.services.boatramp
Cloudflare generate beta
Generate a Worker + Containers deployment — configs, Dockerfile, and edge Worker — from one command.
cloudflare
13 / AGENT-NATIVE
Hand the helm to an agent.
MCP server
The same binary ships a Model Context Protocol server, so an agent like Claude (Desktop, Code) or Codex operates your control plane in natural language — list sites, activate or roll back, tail logs, invoke functions, inspect the cluster.
boatramp mcp
Two transports
A
boatramp mcp stdio subcommand a desktop agent spawns, and a POST /mcp endpoint on boatramp serve to drive a node over the network — on by default, same tool set on both.stdio · /mcp
Typed, enumerated tools
One named tool per control-plane operation — no generic passthrough — so every call is legible in an audit log rather than an opaque shell.
no passthrough
Your token, your authority
Every call runs with the caller's own bearer, re-checked per operation; hand the agent a least-privilege token and the write and fleet-admin tools simply
403. The endpoint grants nothing the token doesn't.least-privilege
Many instances, one agent
Register several boatramp nodes by name in
mcp.toml and address them per request ("on prod, …"); secrets are stored as specs, never resolved into the file.mcp.toml
Kill-switch & rebinding guard
Turn the HTTP surface off fleet-wide with no restart (
config set mcp.enabled false), and a Host-header allowlist keeps it loopback- or origin-only as a DNS-rebinding defence.mcp.enabled
Agent-ready scaffold
Ships an
AGENTS.md guide so an AI coding agent (Claude Code, Codex, …) can build a project on boatramp and deploy it out of the box.AGENTS.md
pre-1.0
Every capability above is implemented and dogfooded — this site runs on it. Interfaces may still shift before 1.0. Start with the quickstart, dig into the docs, or come crew it.