fuse build
Run a Fusefile's setup phase once and snapshot the result
fuse build [path] [flags]
Boots a throwaway environment, runs the Fusefile’s
setup: phase inside it, snapshots the resulting disk, destroys the
environment, and prints the snapshot ID. Pass that ID to
fuse up --from-build to boot an environment with the
setup work already done.
# build once, capture the artifact id
id=$(fuse build)
# boot from it as many times as you like; setup does not rerun
fuse up --from-build "$id"
Only the ID goes to stdout, so $(fuse build) captures it cleanly. Progress
and warnings go to stderr.
Why this exists
setup: normally compiles into the environment’s startup script, which the
orchestrator runs synchronously inside the create request under a 30 second
ceiling that is not configurable in the shipped binary. Any real setup step, an
apt-get install included, routinely exceeds it.
fuse build runs the same lines through the exec path instead, which allows
600 seconds, and shows their output so a failing build is debuggable. The
result is captured once rather than re-run on every boot.
An artifact is a rootfs file on the host that produced it, and Fuse has no object storage. It is no longer confined to that host, though: an environment seeded from an artifact prefers a host that already holds it, and when no such host can take the workload the artifact is copied directly to one that can. See The layer cache.
Flags
| Flag | Purpose |
|---|---|
-f, --file |
Path to the Fusefile. Default: a discovered Fusefile, or a positional path argument. |
--name |
Name for the build artifact, recorded as its lookup key. Default: the Fusefile’s parent directory name. |
--secret |
Secret as key=value. Repeatable. Overrides --secrets-file on key collision. |
--secrets-file |
Path to a file of KEY=VALUE secret lines. |
--allow-empty-secrets |
Treat an empty value as satisfying a required secret. |
--keep |
Leave the builder environment running instead of destroying it. For debugging a failed build. |
--plan |
Print the derived setup layer cache plan and exit without building anything. |
--no-cache |
Ignore the Fusefile’s cache block and run every setup step. |
Path resolution matches fuse up:
-f/--file, then a positional argument, then the first discovered Fusefile in
the working directory.
Finding an artifact later
--name is recorded on the snapshot so an artifact can be found without its
random ID:
fuse build --name api
fuse snapshot list --mode build --name api -o json
What is captured
Only the setup: phase runs. The run: command is not executed, so a build
never starts your application. On a later fuse up --from-build, setup: is
skipped and only run: executes, since the setup result is already baked into
the artifact’s rootfs.
A Fusefile with no setup: steps has nothing to build and fuse build exits
non-zero rather than producing an empty artifact.
The layer cache
build is where the setup: phase actually runs, so the
setup layer cache describes
exactly this command’s work, and build is the only command that produces
layers. --plan prints the derived keys and exits, and --no-cache ignores the
Fusefile’s cache block for one run. The plan is the same one
fuse up --plan prints for the same Fusefile: there is one
key derivation, not one per command.
With caching enabled, the command resolves the chain deepest first and stops at the first hit. A hit at step N means every step before it is satisfied by that same artifact, so the first hit found walking backwards is the most work that can be skipped, and a warm cache costs one lookup rather than one per step. The builder then boots from that artifact instead of the base image, and only the steps it did not cover run.
Those remaining steps run one at a time, each snapshotted as its own layer, up to the first step that cannot be cached. Everything from there on runs as a single command, since none of it can be captured anyway.
If a step fails, every layer taken before it is kept. That is the point of
snapshotting per step: fix the setup line that broke, run again, and the build
resumes from the last good layer instead of starting over. The builder
environment is still destroyed unless --keep is set.
Nothing about the cache can fail a build that would otherwise have succeeded. A mixed-architecture fleet, an unreachable orchestrator, and a cold cache all fall back to running the setup phase in full.
fuse build --plan
fuse build --plan -o json
When caching is enabled, the plan is also derived before the builder boots, so a
setup[].inputs entry that matches no files fails immediately rather than after
a VM is up and holding host capacity.
--from-build and a Fusefile image: are mutually exclusive: both name the
rootfs to boot from.
Exit status
fuse build exits non-zero if the builder fails to come up, if the setup phase
exits non-zero, or if the snapshot cannot be taken. In each case the builder
environment is destroyed before returning unless --keep is set, so a failed
build does not leave a VM holding host capacity.