Workloads
A workload is one container image plus everything Brig needs to schedule
it: replica count, resource ask, ports, volumes, env, secrets, placement
rules, autoscaling, mesh policy, and snapshot policy. You describe it in a
TOML file and brig deploy it.
Minimal example
Section titled “Minimal example”name = "whoami"image = "traefik/whoami:latest"instances = 1cpu = "100m"memory = "32Mi"That’s enough to deploy. brig deploy whoami.brig.toml parses, validates,
schedules one replica on a healthy node, pulls the image, and gives the
workload a public URL.
Top-level fields
Section titled “Top-level fields”| Field | Required | Description |
|---|---|---|
name | yes | 1–63 chars, [a-z0-9-], no leading/trailing -. Unique per workspace. |
image | yes | OCI image reference, e.g. ghcr.io/me/api:v13. (Local image if [deploy] source = "local" — see Build from local image.) |
instances | yes | Replica count, 1–100. Brig keeps this many running across the fleet. |
cpu | no | CPU ask. "500m" = 0.5 vCPU, or "1.5" = 1500m. |
memory | no | Memory ask. "512Mi", "1Gi", or raw "1024" (MiB). Binary units only — no decimal M/G. |
command | no | Override the image’s CMD. |
ports | no | Published ports. See Network exposure. |
env | no | Inline environment variables (map). Keys are POSIX-shaped ([A-Za-z_][A-Za-z0-9_]*). |
secrets | no | Names of workspace secrets to inject as env vars. See Secrets. |
public | no | true (default) gives a managed *.brig.run URL + TLS. false keeps the workload mesh-internal (bring your own ingress). |
Volumes
Section titled “Volumes”[[volume]]mount = "/var/lib/data"A bare [[volume]] with just a mount is a local volume — a node-pinned
Docker named volume, one per replica, persisted across restarts on the same
node. For a cloud block device that survives node loss, set class = "ebs"
and a size:
[[volume]]mount = "/var/lib/data"class = "ebs"size_gib = 20Add a snapshot policy to drive recurring backups:
[[volume]]mount = "/var/lib/data"class = "ebs"size_gib = 20snapshot_every = "24h" # Go duration, minimum 1hsnapshot_keep = 7 # 1..365 most-recent retainedsnapshot_destination = "prod" # name of a workspace destination; omit = defaultSee Volumes for the full lifecycle and Snapshots for backup/restore.
Network exposure
Section titled “Network exposure”ports = ["80:whoami.example.com", "9000"]Each entry is <container-port>[/<proto>][:<ingress-hostname>]:
"80"— expose container port 80 (TCP) inside the mesh only."80:api.example.com"— also route this hostname to it at the edge."9000/udp"— UDP port.
The Brig proxy mesh terminates TLS at the edge and routes to the nearest
healthy replica. Replicas reach each other inside the mesh by workload name —
no need to publish ports for internal traffic. See Networking
for service discovery, custom domains, and mesh policy (allow_from /
allow_to, sticky routing).
Placement
Section titled “Placement”By default Brig spreads replicas across distinct nodes (anti-affinity). The
[placement] block changes that:
[placement]requires_labels = ["us-east", "ssd"] # only schedule on nodes with ALL these labelsnode = "node-7" # hard-pin every replica to one nodetogether = true # co-locate all replicas on a single nodesame_node_only = true # refuse cross-node inbound mesh calls| Field | Description |
|---|---|
requires_labels | Scheduler considers only nodes carrying all of these labels. Set labels with brig node labels. |
node | Pin all replicas to one node by id. |
together | Co-locate all replicas on a single node instead of spreading them. |
same_node_only | The mesh proxy returns 403 to any request that arrived from another node — defense-in-depth for sidecar databases. |
Autoscaling
Section titled “Autoscaling”Add an [autoscale] block to let Brig manage the replica count by CPU:
instances = 2 # must sit within [min, max]
[autoscale]min = 2max = 10cpu_target = 0.70 # target average CPU utilisation (0..1); default 0.70scale_up_after = "1m" # sustained breach before scaling up; default 1mscale_down_after = "5m" # sustained slack before scaling down; default 5mAutoscaling is on when min > 0 and max >= min. A controller sweeps
roughly every 30s, computes average CPU across running replicas, and steps the
count up or down by one, respecting the cooldown windows so it doesn’t flap.
brig scale still works for a manual override within the band.
Rollouts
Section titled “Rollouts”brig deploy is the same command for create and update. Brig diffs the new
spec against the running version and rolls forward one replica at a time. Watch
it inline with --watch, or check status separately:
brig deploy whoami.brig.toml --watchbrig status # one-screen fleet healthbrig inspect whoami # per-replica detail + recent eventsIf a rollout gets stuck (image pull fail, health check red) Brig pauses and
emits a RolloutStuck event (visible in brig inspect). Fix the underlying
issue and run brig deploy again — the rollout resumes from where it stalled.
To revert to the previous version:
brig rollback whoamiScaling
Section titled “Scaling”brig scale whoami=5 # set instances to 5This is purely a count change and does not bump the workload version. If
you store the TOML in git, keep its instances (or [autoscale] band) in sync
— the next brig deploy reconciles back to whatever the file says.
Environments
Section titled “Environments”Every workload command takes --env to target a non-production environment.
A bare name resolves to a sibling env file (--env staging → .env.staging);
an explicit path is used as-is (--env ./infra/.env.eu). Without --env,
single-workload commands default to production; brig ps lists all envs.
Environments are isolated in the mesh — a staging replica can’t reach a
production one even if the workload names collide.
Build from a local image
Section titled “Build from a local image”To ship an image built on your laptop without pushing to a registry, declare a local source and name the target node(s):
[deploy]source = "local"Brig docker saves the local tag, streams it over SSH to each --node,
retags it brig-local/<workload>:<tag>-<digest>, and triggers a release. The
agent recognises the brig-local/ prefix and skips the registry pull. You can
also do this ad-hoc without a [deploy] block:
Full field reference
Section titled “Full field reference”The complete TOML grammar — every field, type, and validation rule — lives in the CLI reference alongside the commands that consume it.