Skip to content
Fuse
Esc
navigateopen⌘Jpreview
On this page

fuse up

Compile a Fusefile and create an environment from it

fuse up [path] [flags]

Reads a Fusefile, compiles it into a resource spec, manifest, and startup script, then creates an environment from the result. Streams provisioning events until the environment settles, unless --no-wait is set.

up returns as soon as the environment reaches running, so it is safe to use in scripts and CI. Reaching running is the only success: up exits non-zero if the environment reaches failed, is destroyed before it comes up, or if the event stream ends before the environment settles at all (a dropped connection or an orchestrator restart mid-provision). To keep watching an environment after it is up, use fuse environment watch, which streams until the environment is destroyed or fails.

Flags

Flag Purpose
-f, --file Path to the Fusefile. Default: the first of the discovered names below, or a positional path argument.
--secret Secret as key=value. Repeatable. Overrides --secrets-file on key collision.
--secrets-file Path to a file of KEY=VALUE secret lines. #-prefixed lines and blanks are ignored.
--allow-empty-secrets Treat an empty value as satisfying a required secret.
--task-id Environment task ID. Default: the Fusefile’s parent directory name.
--gateway-url Gateway URL, matching fuse environment create.
--gateway-token Gateway token.
--dry-run Print the create request this Fusefile would post and exit without connecting to the orchestrator.
--no-wait Create the environment without streaming provisioning events.
--from-build Boot from a fuse build artifact instead of a base image. Skips the setup: phase.
--plan Print the derived setup layer cache plan and exit without creating anything.
--no-cache Ignore the Fusefile’s cache block and run every setup step.
--wait-healthy After the environment is running, keep waiting until its healthcheck reports passing.
--health-timeout How long --wait-healthy waits for a passing verdict before giving up. Default 2m.
--show-copy Print what the copy: block ships, and what .fuseignore dropped, before creating anything.

--from-build is mutually exclusive with both --plan and --no-cache: a --from-build boot runs no setup steps, so there is no layer plan for it to print and nothing for it to re-run. Use those flags on fuse build, which is where the setup phase runs. --dry-run and --plan are mutually exclusive for a different reason: both print and exit, and they print different things.

The gateway carries a credential, so it is a flag rather than a Fusefile field. Setting it here is the only difference that remained between the Fusefile path and fuse environment create.

Waiting for healthy

Reaching running means the VM booted and the startup script returned. It does not mean your app is serving: nothing has dialled it. --wait-healthy closes that gap by keeping up waiting until the environment-level healthcheck you declared reports passing.

fuse up --wait-healthy --health-timeout 5m

It needs a healthcheck: block in the Fusefile; without one there is no verdict to wait for and up says so instead of hanging until the timeout. It is also mutually exclusive with --no-wait, which returns before the environment is even running.

A failing verdict along the way is not a failure. A probe can legitimately fail while the app is still coming up, which is what start_period exists for, so only the timeout ends the wait unhappily, and the error carries the last verdict and its reason:

environment fuse-api did not report healthy within 2m0s (failing: GET http://127.0.0.1:8080/healthz returned 502)

The verdict is produced in the guest and read back by the orchestrator on its reconcile tick (30s by default), so expect up to a tick of lag between the probe passing and up returning.

The layer cache

up consumes the layer cache but never produces it. Populating it would mean snapshotting mid-boot, which means pausing an environment somebody asked to have running; fuse build is the command that makes layers.

With cache: {enabled: true} in the Fusefile, up resolves the chain deepest first and, on a hit, boots from that artifact and runs only the setup: steps it did not already cover, followed by run:. On a miss it boots the base image and runs the setup phase in full, exactly as it always has.

A hit never costs you a working up. If the artifact lives on a host that cannot take the workload, the orchestrator places the environment elsewhere and moves the artifact to it; if the cache cannot be consulted at all, the boot goes cold. The files: and copy: blocks are re-sent either way, since those are authoring inputs that may have changed since the artifact was baked.

Copying local files in

A Fusefile’s copy: block is expanded here, on your machine, before anything is posted: up resolves each from relative to the Fusefile rather than to your working directory, walks a directory source into one entry per regular file, and sends the result alongside the manifest so the files exist in the guest before setup: and run: execute.

Everything that can go wrong with a source therefore fails locally, naming the entry: a path that does not exist, a symlink (never followed), or a block over the 512 KiB total. --dry-run runs the same walk, so it catches all three without contacting the orchestrator.

The walk is filtered through the .fuseignore next to the Fusefile, which applies whether or not you wrote one: .git/, node_modules/, .env and a handful of others are dropped by default. An ignored directory is pruned rather than walked, so what it holds counts against neither the 512 KiB cap nor the time the walk takes.

Seeing what copy: ships

--show-copy prints the result of that walk before anything is created:

$ fuse up --show-copy
copy ./src -> /workspace/src
  412 files, 311.4 KB (4 skipped by .fuseignore, 2 by the defaults)
copy ./start.sh -> /workspace/start.sh
  1 file, 842 B
total: 413 files, 312.2 KB (limit 512.0 KB)

It is a report, not a mode: up goes on to create the environment. Pair it with --dry-run to stop before the orchestrator is contacted at all.

The skip counts are per path, not per file, because an ignored directory is never walked: pruning node_modules/ counts as one skip whatever is inside it. A missing file with a count next to .fuseignore means a pattern you wrote; one counted against the defaults means a ! line will bring it back.

Path resolution

-f/--file wins if set, then a positional argument. With neither, up looks in the working directory for these names, in order, and uses the first that exists:

Fusefile   Fusefile.yaml   Fusefile.yml   fusefile.yaml   fusefile.yml

If none of them is there, the error names all five rather than reporting a failed open of one. Discovery does not walk up to a parent directory: one level too deep, pass -f.

Both -f and the positional argument name the file itself, neither appends a Fusefile name to a directory, so pointing either at a directory fails with read ./services/api: read ./services/api: is a directory (the operation and path appear twice because the CLI prefixes an error that already names them).

fuse up                                 # ./Fusefile, ./Fusefile.yaml, ...
fuse up ./services/api/Fusefile
fuse up -f custom.fusefile.yaml

Secrets

fuse up --secret pg_password=hunter2
fuse up --secrets-file .env.secrets
fuse up --secrets-file .env.secrets --secret pg_password=override  # override wins on collision

If any secret named in the Fusefile’s secrets list is missing from the resolved set (flags plus file), up fails fast with the list of missing names rather than creating a broken environment.

An empty value does not count as supplied: --secret pg_password= is a typo far more often than a deliberate empty credential, and an environment that boots with one fails later and further from the cause. Pass --allow-empty-secrets when the empty value is intentional.

Task ID

The Fusefile has no task ID field, so with no --task-id the CLI derives one from the Fusefile’s parent directory name and says so before it creates anything:

fuse up
# no --task-id: using "my-service", derived from the Fusefile's directory

Two checkouts of the same repository derive the same ID, so pass --task-id explicitly when that matters.

Dry run

--dry-run prints the create request up would post and exits before it connects to anything, so it needs no context and no configured host. Everything up to the network still runs, which means a dry run still applies the secret gate and still reports a derived task ID.

The output is the same rendering fuse compile produces, and honours -o json for a body you can diff or post by hand. Secret values are never printed, only the names the create would require.

fuse up --dry-run
fuse up --dry-run -o json | jq .spec

Examples

fuse up
# creating environment fuse-abc123 (task my-service)
# provisioning
# running
# environment       fuse-abc123  running
# task              my-service
# host              build-3
# agent             10.0.0.4:19551
# endpoint http     10.0.0.4:41337  ->  guest :8080
# shell             fuse environment shell fuse-abc123

The summary is printed once the environment settles at running. The endpoint rows are the ports the Fusefile’s expose: block published, paired with the guest port each one forwards to. The agent row is the guest agent’s own address, not an exposed port. In -o json mode the summary is the environment object instead, so stdout stays pipeable.

fuse up --no-wait
# creates immediately, does not stream events; watch separately with
# `fuse environment watch <id>`
fuse up --gateway-url https://gw.internal --gateway-token "$GW_TOKEN"

Startup script timeouts

The Fusefile’s setup: and run: compile into one startup script that the orchestrator runs synchronously inside the create request, so its ceiling is bounded by the control plane’s HTTP write timeout. A setup phase that exceeds it fails the create:

startup script did not complete in time after 30s: ...
  the startup script runs synchronously inside create, so its ceiling is bounded by the
  control plane's http write timeout. raise it a little with `startup_timeout` in the
  Fusefile, or move the slow work out of `setup:` and bake it once with `fuse build`,
  then boot it with `fuse up --from-build <id>`

startup_timeout buys a little headroom but cannot exceed the fleet’s ceiling. For anything genuinely long, such as an apt-get install, run it once with fuse build and boot the artifact with --from-build: that path runs the setup phase through exec under a much larger ceiling, and later boots skip it entirely.

See Fusefile for the full field reference, fuse init to scaffold one, and fuse compile to print what one compiles into without creating anything.

Was this page helpful?