{{define "fleet_byo"}}{{template "top" .}} {{if .Flash}}
{{end}} {{if .FlashErr}}{{end}}Fleet · {{.Account.Name}}
Run your apps on hardware you own. Your boxes dial out to the platform over an outbound tunnel; nothing ever connects in.
From a terminal signed in to this console:
carlos fleets create -bucket <your-bucket> <name>
carlos fleets add-box <name> <label>
(shown once — the console does not store or re-show the plaintext)
ROTATION IS NOT REVOCATION: this refuses the box's NEXT dial-in with the OLD token, but does NOT evict a channel it already holds — a COMPROMISED box needs Detach, not another Rotate.
On the box, in a root-owned env file the agent's unit loads (see Hardening below):
AWS_SHARED_CREDENTIALS_FILE=/etc/carlos/credentials
CARLOS_HIBERNATE_BUCKET=<your-bucket>
CARLOS_FLEET=<name>
CARLOS_FLEET_BOX=<label>
CARLOS_REGION=fleet/<name>
CARLOS_RELEASE_PUBKEY=<this deployment's release public key>
CARLOS_TUNNEL_URL=<this deployment's tunnel address>
CARLOS_TUNNEL_TOKEN=<from carlos fleets add-box <name> <label> — shown once>
CARLOS_TUNNEL_NAME=<name>/<label>
Release pointers are Ed25519-signed; without CARLOS_RELEASE_PUBKEY the
box has no key to verify against and refuses to adopt anything.
CARLOS_FLEET_BOX is optional and defaults from
CARLOS_TUNNEL_NAME's label half. AWS_SHARED_CREDENTIALS_FILE points at
an access key for the bucket above — your own bucket only — written root-owned
mode 600 alongside the env file.
No CARLOS_DEPLOYMENT_BUCKET, and no AWS credentials for the
platform's own bucket, belong in this file at all: the box reads its app releases and writes its
heartbeats through the console's edge, over HTTPS, using the same tunnel token it already dials
in with — not a bucket-level AWS grant.
Optional override: CARLOS_STATUS_PREFIX=fleets/<name>/ — the box
defaults to this on its own; set it explicitly only if you're pointing status/heartbeats
somewhere non-standard.
A box still running a pre-fleet-API agent build needs
CARLOS_DEPLOYMENT_BUCKET set to the platform's own deployment bucket, plus an AWS
credential granting it RW there, in addition to the hibernate-bucket vars above. New boxes should
not be configured this way — it is kept working for boxes that haven't upgraded yet, not as a
choice.
ProtectSystem=strict and
NoNewPrivileges=yes — see internal/host/units/ in the platform repo
for the reference shapes.The box appears on your fleet page within minutes — it self-reports on a heartbeat cadence, not
instantly. From there, place an app on it with carlos apps place or from the app's
Instances tab.