Skip to content
shippy

Client configuration

The shippy client reads its settings from three places: a project's shippy.toml, your own user file, and SHIPPY_* environment variables. This page lists every one of them with its default. Come here when you want to change how shippy behaves on one machine or for one project.

You need none of it to start. With no file and no variable, shippy build uses a local cache in ~/.cache/shippy and no remote.

Where settings come from

Loading diagram...
PlaceWho writes itWhat it holds
SHIPPY_* variablesyou, CIany setting below
~/.config/shippy/config.tomlshippy setup, youthe remote's URL, where your token is, and the local store's limits
shippy.toml at the workspace rootthe projectcargo settings, cache switches, and the remote it suggests

The rules:

  • The environment wins. A variable that is set overrides both files. CI is usually configured this way: SHIPPY_REMOTE and SHIPPY_TOKEN, both in the pipeline's environment.
  • The remote is yours to name. It is SHIPPY_REMOTE, else the URL in your user file, else none. A project's shippy.toml may name one, and it is used only once you named the same one: a cloned repository cannot point you at a server, with your token or without it. A build that leaves a project's remote unused says so and how to use it.
  • Your token goes to your remote only. The token in the user file is sent only to the URL in the same file. If SHIPPY_REMOTE names another server, the file's token is left out.
  • What is shared by all your projects is yours to set. The local store's limits (max_size, max_age) are variables or keys of your user file, never of a project's shippy.toml; the checkout is no wider than the repository unless SHIPPY_WS says so; and a project's [env] sets no SHIPPY_* variable.
  • Every other setting is a variable or a key in shippy.toml, and the variable wins.

On/off variables read 0, false, off and no as off. Any other value is on.

shippy.toml

shippy.toml sits at the root of the cargo workspace. Every key is optional. An unknown key is an error, so a typo does not go unnoticed.

[cargo]
toolchain = "nightly"
config = ['profile.dev.debug="line-tables-only"']
args = []
 
[remote]
url = "http://box:7447"
prefetch = true
exec = "deps"
exec_jobs = 24
 
[cache]
build_scripts = true
share_scripts = ["a"]
local_scripts = []
linked_outputs = true
fixed_paths = false
root = ".."
gc = true
 
[env]
SOURCE_DATE_EPOCH = "1794500000"

[cargo]

How cargo is run. shippy-bench tune finds these values (tune a project).

SettingDefaultWhat it does
toolchainnoneA rustup toolchain, passed as cargo +<toolchain>. A +toolchain on the command line wins.
config[]Each entry becomes --config <entry>.
args[]Extra arguments placed after the subcommand.

[remote]

The box this project uses. A URL may end in a slash or not.

SettingDefaultWhat it does
urlnoneThe box this project suggests, such as http://box:7447. Used only by a user or pipeline that named the same one (SHIPPY_REMOTE, shippy setup); anyone else builds without it and is told how to use it.
prefetchtruefalse never fetches a build's results before cargo starts, and never sends the list of results a build used.
execfalseWhich cache misses the box compiles: false, true (same as "auto"), "deps" or "always". See remote execution.
exec_jobseight per core, at most 64How many crates cargo works on at once while the box compiles.

The exec modes:

ValueWhat the box compiles
falsenothing; every miss compiles here
"deps"only crates from a registry or a git repository
true or "auto"every miss, except a workspace crate this target directory can rebuild incrementally
"always"every miss

[cache]

What is cached and how the local store is kept.

SettingDefaultWhat it does
rootthe git repository around the workspaceThe directory two checkouts have in common, relative to this file: one between the workspace and the git repository around it. Paths under it count as the same place on every machine (paths), and its files are what a build may send, so a directory above the repository is ignored here and named with SHIPPY_WS.
remaptrueRecord virtual paths in compiler output, so results do not depend on where the checkout lives. false keeps real paths, and results then only match the same paths.
pushtrueUpload what this machine builds.
primetrue, false where CI is setAfter a build that restored workspace crates, compile them once more in the background for their incremental state, so the first rebuild after an edit is as fast as the next. false never does.
claim_incrementalfalseAlso upload results compiled from incremental state (a rebuild after an edit). The box compiles from nothing and never matches those.
keep_incrementalfalseAlso keep those results in the local store, and restore them when the same sources come back. Every rebuild after an edit then hashes and stores what it wrote.
build_scriptsdependencies' scriptstrue caches every package's build-script runs; false none (build scripts).
share_scripts[]Workspace packages whose build scripts read only their own package and what they declare, so their runs may be shared like a downloaded package's.
local_scripts[]Packages whose build scripts always run on the machine that builds.
linked_outputstrueCache executables and C-compatible libraries too. false leaves them to the linker.
fixed_pathsunsettrue runs cargo with the checkout mounted at /shippy/at/ws, so checkouts at any path share everything; it needs bubblewrap. Unset, the procedural macros cargo downloaded are compiled with cargo's home named /shippy/at/cargo, where the machine allows it, so users with other cargo homes share a macro that holds its directory and the crates expanded with it. false leaves every directory where it is. See paths.
gctruefalse: this project's builds never clean the store. shippy gc still does.

max_size and max_age are not keys of a project: the local store is one for all your projects, and its limits are in your user file or in SHIPPY_MAX_SIZE and SHIPPY_MAX_AGE. A shippy.toml that has them is read, and the build says they are ignored.

[env]

A table of extra environment variables for cargo. Use it for variables that reach every key, such as SOURCE_DATE_EPOCH, so every machine builds the same way. A SHIPPY_* variable here is ignored, and the build says so: shippy's own settings are the user's. A proxy variable here is for cargo and the build; the box is reached through the proxy of the environment shippy itself is started in.

The user file

shippy setup --remote http://box:7447 --token-file token.txt

shippy setup writes config.toml and token in $XDG_CONFIG_HOME/shippy, else ~/.config/shippy. SHIPPY_CONFIG_DIR names another directory. Both files are readable by their owner only.

# Written by `shippy setup`. SHIPPY_REMOTE and SHIPPY_TOKEN are over it.
[remote]
url = "http://box:7447"
token_file = "/home/alice/.config/shippy/token"
 
# Yours to add: how large the local store may get. `shippy setup` keeps it.
[cache]
max_size = "50GB"
max_age = "14d"
SettingDefaultWhat it does
urlnoneThe box. SHIPPY_REMOTE is over it.
token_filenoneThe file your token is in. shippy setup keeps it beside this file; you may name one anywhere, such as a secret a pipeline mounts. shippy build reads it and hands the token to its compiler wrappers (SHIPPY_TOKEN_HANDOFF). A wrapper that plain cargo runs (shippy wrapper) reads it too where it can read cargo's own environment (Linux); elsewhere it takes a token only from a regular file in this file's directory, and shippy doctor says so.
max_sizehalf of the store's size plus free space, at most 50GBHow large the local store may get, such as "50GB", or "off". SHIPPY_MAX_SIZE is over it.
max_ageno limitAlso remove results not used for this long, such as "14d". SHIPPY_MAX_AGE is over it.

A broken user file is treated as no file, so it never fails a build. shippy doctor says what is wrong with it. A box at a plain http address that is not this machine gets your token unencrypted: shippy setup and shippy doctor say so, and a build says it once.

Environment variables

Every SHIPPY_* variable the client reads. Rows marked set by shippy, not by you are variables the front end sets for the wrappers it starts; leave them alone.

Remote

SettingDefaultWhat it does
SHIPPY_REMOTEnoneURL of a shippyd, such as http://box:7447.
SHIPPY_TOKENnoneBearer token for the remote.
SHIPPY_CONFIG_DIR$XDG_CONFIG_HOME/shippy, else ~/.config/shippyWhere the user file is.
http_proxy, https_proxy, no_proxynoneThe remote is reached through the proxy for its scheme, unless no_proxy lists its host. Read from the environment shippy is started in.
SHIPPY_PROXYset by shippy, not by youThe proxy the front end found for the remote, for its wrappers: empty when the box is reached directly.

Cache

SettingDefaultWhat it does
SHIPPY_STORE~/.cache/shippyThe local store directory.
SHIPPY_DISABLE01 runs plain rustc.
SHIPPY_REMAP10 keeps real paths in compiler output. Results then only match the same paths.
SHIPPY_PUSH10 never uploads.
SHIPPY_PRIME1, 0 where CI is set0 never compiles restored workspace crates again for their incremental state; wait has the build end only when that is done.
SHIPPY_JOBSERVER10 leaves cargo the jobserver it makes itself. By default shippy makes it, with as many jobs, as a fifo cargo is given by name, so that cargo starts its compilers without forking (for build, check, clippy, rustc and doc, without -j on the command line, with cargo 1.70 or later).
SHIPPY_CLAIM_INCREMENTAL01 also uploads what was compiled from incremental state.
SHIPPY_KEEP_INCREMENTAL01 also keeps what was compiled from incremental state in the local store.
SHIPPY_LINKED10 leaves executables and C-compatible libraries to the linker.
SHIPPY_SCRIPTSdepsWhich build-script runs are cached: 1 every package's, deps those of registry and git dependencies, 0 none.
SHIPPY_SCRIPTS_SHAREfrom share_scriptsComma-separated workspace packages whose script runs may be shared.
SHIPPY_SCRIPTS_LOCALfrom local_scriptsComma-separated packages whose scripts always run here.
SHIPPY_SCRIPT_MAX_BYTES1073741824 (1 GiB)The most bytes a shared script run may declare: the package and what its dependencies export.
SHIPPY_SCRIPT_MAX_FILES50000The same in files.
SHIPPY_SCRIPT_TIMEOUT1800Seconds a script's run on the box may take, waiting included, before it runs here.
SHIPPY_MAX_SIZEhalf of the store's size plus free space, at most 50GBHow large the local store may get, such as 50GB or off.
SHIPPY_MAX_AGEno limitAlso remove results not used for this long, such as 14d.
SHIPPY_GC10 never cleans the store after a build. shippy gc still does.
SHIPPY_GC_GRACE15mHow long what was just stored or used is left alone.
SHIPPY_GC_INTERVAL10mHow often a build starts a cleanup round.

Prefetch and upload

SettingDefaultWhat it does
SHIPPY_PREFETCH10 never fetches a build's results before cargo starts.
SHIPPY_PREFETCH_JOBS16Connections a prefetch downloads over.
SHIPPY_PREFETCH_MAX_BYTES20GBThe most a prefetch downloads, or off. Results are fetched in the list's order while they fit; the rest is fetched crate by crate.
SHIPPY_PREFETCH_TIMEOUT600Seconds a prefetch may take before cargo starts without the rest.
SHIPPY_PUSH_JOBSsame as SHIPPY_PREFETCH_JOBSConnections an upload sends over.
SHIPPY_COMPRESSautomatic1 always sends and asks for blobs as a zstd stream, 0 never. Unset, they are compressed unless the box is on this machine or answers within a few milliseconds.

Remote execution

See remote execution.

SettingDefaultWhat it does
SHIPPY_EXEC0Which misses the box compiles: 0, deps, 1 or auto (all but the dependencies this machine has a core for and the crates it is rebuilding), always.
SHIPPY_EXEC_JOBSeight per core, at most 64Crates cargo works on at once while the box compiles.
SHIPPY_EXEC_RECHECK01 compiles here as well when the box's compiler failed, and believes this machine's.
SHIPPY_EXEC_TIMEOUT900Seconds a remote compilation may take, waiting included, before this machine compiles the crate.
SHIPPY_EXEC_MAX_BYTES64 MiB, or 1 GiB for a downloaded packageThe most a crate may declare when its whole package is sent. Past it the crate compiles here, or is sent without the packages below its own when it loads no procedural macro.
SHIPPY_EXEC_MAX_FILES20,000, or 50,000 for a downloaded packageThe same in files.
SHIPPY_EXEC_INLINE4194304 (4 MiB)The most bytes of inputs a request to compile brings with it. 0 sends nothing along.
SHIPPY_LOCAL_JOBSone per coreCompilers this machine runs at once while SHIPPY_EXEC is on, and the jobs a build script that runs here is told to start. With auto, a dependency the cache misses compiles here while fewer than that many run. 0: no limit, and auto sends the box every miss it may compile.

Broker

The broker keeps a few connections to the box open for the whole build, and the per-crate wrappers share them.

SettingDefaultWhat it does
SHIPPY_BROKER10 has every crate connect to the box itself.
SHIPPY_BROKER_CONNECTIONS8Connections the crates of a build share for lookups and blobs.
SHIPPY_BROKER_SOCKETset by shippy, not by youThe broker's socket path.
SHIPPY_BROKER_FORset by shippy, not by youA digest of the remote and token the broker was started for.
SHIPPY_TOKEN_HANDOFFset by shippy, not by youThe file the front end keeps a token in while the build runs, readable by you alone, for the wrappers: one from SHIPPY_TOKEN, or from a token_file that is not beside your user file.

Paths

See paths.

SettingDefaultWhat it does
SHIPPY_FIXEDfixed_paths, else home1 runs cargo with the checkout mounted at /shippy/at/ws, which needs bubblewrap. home has the procedural macros cargo downloaded compiled with cargo's home named /shippy/at/cargo, also for root. 0 leaves every directory where it is.
SHIPPY_WSroot, else the git repository around the workspaceThe checkout, when it is not the git repository around the workspace: any directory, also one above the repository, which a project's root cannot name. The front end also sets it for the wrappers.
SHIPPY_INSIDEset by shippy, not by youMarks processes inside the fixed place, or (home) in a build that has cargo's home at its fixed place, so a nested shippy stays in it.
SHIPPY_REAL_WS, SHIPPY_REAL_TARGET, SHIPPY_REAL_CARGO_HOMEset by shippy, not by youThe real directories behind the fixed ones.
SHIPPY_AT_HOMEset by shippy, not by youThe cargo home a build was to have at its fixed place, for what the front end starts after cargo.

Debug

SettingDefaultWhat it does
SHIPPY_DEBUGunsetSet: the wrappers and the front end say more on stderr, such as why a step was skipped.
SHIPPY_QUIETunsetSet: no summary line after a build.
SHIPPY_PROFILEunsetSet: each restored crate, each restored build-script run, each compilation on this machine and the front end append where they spent their time to <store>/sessions/<session>.profile: microseconds for each phase, before= for what the process did before the first, and cpu= for the processor time it used in all.
SHIPPY_CARGOcargoThe program the front end runs in place of cargo.

Internal

SettingDefaultWhat it does
SHIPPY_SESSIONset by shippy, not by youNames the build, so its wrappers write one session log.
SHIPPY_LOCAL_JOBSERVERset by shippy, not by youNames this machine's jobserver to the wrappers and the build scripts' launchers: the one shippy made for cargo, or the machine's own when cargo is given more jobs than there are cores.

Go deeper