fuse compile
Print what a Fusefile compiles into, without creating anything
fuse compile [path] [flags]
Reads a Fusefile, compiles it into a resource spec, manifest, startup script, exposed ports, and required secret names, then prints the result. Nothing is created and nothing is sent anywhere.
compile is entirely client-side: it makes no HTTP request, so it works with no
context configured, no host selected, and no network reachable. That makes it
usable in CI and in code review to see exactly what a Fusefile change does to
the request fuse up would post.
Secret values are never accepted or printed. compile deliberately has no
--secret or --secrets-file flag: it lists the secret names the environment
requires and emits secrets as an empty object in the wire form, because values
are supplied at fuse up.
Flags
| Flag | Purpose |
|---|---|
-f, --file |
Path to the Fusefile. Default: a discovered Fusefile, or a positional path argument. |
--task-id |
Task ID to render. Default: the Fusefile’s parent directory name, matching fuse up. |
--format |
Output format: text | json | yaml. Overrides the global -o/--output. |
--only |
Print one part undecorated: spec | startup-script | manifest | expose | secrets. |
--from-build |
Compile as fuse up --from-build would: set seed_snapshot_id and send the run: phase alone. |
Path resolution is identical to
fuse up: -f/--file first, then a
positional argument, then the first Fusefile discovered in the working
directory.
fuse up --dry-run prints the same thing this command does, for the cases
where you want the compiled request without switching commands.
Without --format, the global -o/--output decides: table (the default)
renders the human view, json renders the wire body. --only selects a single
part and cannot be combined with --format; passing both is an error rather
than a silent precedence rule.
Human output
fuse compile
task id my-service
spec
cpus 2
ram mb 2048
storage gb 10
max runtime s 3600
image ghcr.io/acme/worker:latest
startup script
set -eu
if (set -o pipefail) 2>/dev/null; then set -o pipefail; fi
mkdir -p '/workspace'
cd '/workspace'
apt-get update -qq
./start.sh
manifest (decoded; sent base64 as manifest_inline)
{"version":"1","machine":{"workspace":"/workspace"},"services":{"postgres":{"image":"postgres:16","ports":[5432],"env":{"POSTGRES_PASSWORD":{"secret":"pg_password"}}}}}
expose
8080 as http
required secrets (values supplied at `fuse up`)
api_token
pg_password
Empty sections are omitted, and the section order is fixed, so two runs over the
same Fusefile are byte-identical and a diff between revisions is readable. The
manifest is printed decoded here; on the wire it travels base64 as
manifest_inline.
Wire output
fuse compile --format json
{
"task_id": "my-service",
"spec": {
"cpus": 2,
"ram_mb": 2048,
"storage_gb": 10,
"max_runtime_seconds": 3600,
"image": "ghcr.io/acme/worker:latest"
},
"manifest_inline": "eyJ2ZXJzaW9uIjoiMSIsIm1hY2hpbmUiOnsid29ya3NwYWNlIjoiL3dvcmtzcGFjZSJ9LCJzZXJ2aWNlcyI6eyJwb3N0Z3JlcyI6eyJpbWFnZSI6InBvc3RncmVzOjE2IiwicG9ydHMiOls1NDMyXSwiZW52Ijp7IlBPU1RHUkVTX1BBU1NXT1JEIjp7InNlY3JldCI6InBnX3Bhc3N3b3JkIn19fX19",
"secrets": {},
"startup_script": "set -eu\nif (set -o pipefail) 2>/dev/null; then set -o pipefail; fi\nmkdir -p '/workspace'\ncd '/workspace'\napt-get update -qq\n./start.sh\n",
"expose": [
{
"port": 8080,
"as": "http"
}
],
"required_secrets": [
"api_token",
"pg_password"
]
}
This is the POST /v1/environments body fuse up would send, with two
differences: secrets is always empty, and required_secrets is added so the
names are visible. It is meant for reading, diffing, and review, not for posting
back to the API.
--format yaml prints the same document with the same keys, which diffs better
in review:
fuse compile --format yaml
task_id: my-service
spec:
cpus: 2
ram_mb: 2048
storage_gb: 10
max_runtime_seconds: 3600
image: ghcr.io/acme/worker:latest
manifest_inline: eyJ2ZXJzaW9uIjoiMSIsIm1hY2hpbmUiOnsid29ya3NwYWNlIjoiL3dvcmtzcGFjZSJ9LCJzZXJ2aWNlcyI6eyJwb3N0Z3JlcyI6eyJpbWFnZSI6InBvc3RncmVzOjE2IiwicG9ydHMiOls1NDMyXSwiZW52Ijp7IlBPU1RHUkVTX1BBU1NXT1JEIjp7InNlY3JldCI6InBnX3Bhc3N3b3JkIn19fX19
secrets: {}
startup_script: |
set -eu
if (set -o pipefail) 2>/dev/null; then set -o pipefail; fi
mkdir -p '/workspace'
cd '/workspace'
apt-get update -qq
./start.sh
expose:
- port: 8080
as: http
required_secrets:
- api_token
- pg_password
Single parts
--only writes one part with no headings, for piping:
fuse compile --only startup-script | shellcheck -
fuse compile --only manifest | jq .services
fuse compile --only spec | jq .ram_mb
fuse compile --only secrets # one required secret name per line
fuse compile --only expose # one "<port> <as>" line per entry
--only manifest prints the manifest JSON exactly as the guest receives it,
and --only startup-script prints the script verbatim, so both pipe straight
into other tools.
Previewing a seeded boot
A fuse build artifact already carries the setup:
phase baked into its rootfs, so fuse up --from-build sends the run: phase
alone. Pass the same flag to compile to see that request instead of the
from-scratch one:
fuse compile --from-build snap-4f1c9a
The compiled output then carries seed_snapshot_id and a startup_script with
no setup lines. Because a build artifact and image both name the rootfs to
boot, passing --from-build for a Fusefile that sets image is an error here,
exactly as it is at fuse up.
What it does and does not check
compile fails with the same diagnostics fuse up would produce at parse and
compile time: an unknown field, a version other than 1, a service with no
image, an env entry setting both value and secret, an out-of-range expose
port, a malformed size or duration, or an invalid GPU/MIG combination.
It knows nothing about the fleet. It cannot tell you whether the image exists
on any host, whether a region matches a registered host, or whether there is
capacity anywhere. Those only surface at fuse up.
Examples
fuse compile ./ci/Fusefile
fuse compile -f Fusefile.gpu --format yaml
fuse compile --task-id review-build --format json
See Fusefile for the field reference,
fuse init to scaffold one, and
fuse up to create an environment from it.