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
| Place | Who writes it | What it holds |
|---|---|---|
SHIPPY_* variables | you, CI | any setting below |
~/.config/shippy/config.toml | shippy setup, you | the remote's URL, where your token is, and the local store's limits |
shippy.toml at the workspace root | the project | cargo 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_REMOTEandSHIPPY_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'sshippy.tomlmay 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_REMOTEnames 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'sshippy.toml; the checkout is no wider than the repository unlessSHIPPY_WSsays so; and a project's[env]sets noSHIPPY_*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).
| Setting | Default | What it does |
|---|---|---|
toolchain | none | A 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.
| Setting | Default | What it does |
|---|---|---|
url | none | The 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. |
prefetch | true | false never fetches a build's results before cargo starts, and never sends the list of results a build used. |
exec | false | Which cache misses the box compiles: false, true (same as "auto"), "deps" or "always". See remote execution. |
exec_jobs | eight per core, at most 64 | How many crates cargo works on at once while the box compiles. |
The exec modes:
| Value | What the box compiles |
|---|---|
false | nothing; 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.
| Setting | Default | What it does |
|---|---|---|
root | the git repository around the workspace | The 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. |
remap | true | Record 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. |
push | true | Upload what this machine builds. |
prime | true, false where CI is set | After 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_incremental | false | Also upload results compiled from incremental state (a rebuild after an edit). The box compiles from nothing and never matches those. |
keep_incremental | false | Also 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_scripts | dependencies' scripts | true 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_outputs | true | Cache executables and C-compatible libraries too. false leaves them to the linker. |
fixed_paths | unset | true 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. |
gc | true | false: 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.txtshippy 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"| Setting | Default | What it does |
|---|---|---|
url | none | The box. SHIPPY_REMOTE is over it. |
token_file | none | The 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_size | half of the store's size plus free space, at most 50GB | How large the local store may get, such as "50GB", or "off". SHIPPY_MAX_SIZE is over it. |
max_age | no limit | Also 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
| Setting | Default | What it does |
|---|---|---|
SHIPPY_REMOTE | none | URL of a shippyd, such as http://box:7447. |
SHIPPY_TOKEN | none | Bearer token for the remote. |
SHIPPY_CONFIG_DIR | $XDG_CONFIG_HOME/shippy, else ~/.config/shippy | Where the user file is. |
http_proxy, https_proxy, no_proxy | none | The remote is reached through the proxy for its scheme, unless no_proxy lists its host. Read from the environment shippy is started in. |
SHIPPY_PROXY | set by shippy, not by you | The proxy the front end found for the remote, for its wrappers: empty when the box is reached directly. |
Cache
| Setting | Default | What it does |
|---|---|---|
SHIPPY_STORE | ~/.cache/shippy | The local store directory. |
SHIPPY_DISABLE | 0 | 1 runs plain rustc. |
SHIPPY_REMAP | 1 | 0 keeps real paths in compiler output. Results then only match the same paths. |
SHIPPY_PUSH | 1 | 0 never uploads. |
SHIPPY_PRIME | 1, 0 where CI is set | 0 never compiles restored workspace crates again for their incremental state; wait has the build end only when that is done. |
SHIPPY_JOBSERVER | 1 | 0 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_INCREMENTAL | 0 | 1 also uploads what was compiled from incremental state. |
SHIPPY_KEEP_INCREMENTAL | 0 | 1 also keeps what was compiled from incremental state in the local store. |
SHIPPY_LINKED | 1 | 0 leaves executables and C-compatible libraries to the linker. |
SHIPPY_SCRIPTS | deps | Which build-script runs are cached: 1 every package's, deps those of registry and git dependencies, 0 none. |
SHIPPY_SCRIPTS_SHARE | from share_scripts | Comma-separated workspace packages whose script runs may be shared. |
SHIPPY_SCRIPTS_LOCAL | from local_scripts | Comma-separated packages whose scripts always run here. |
SHIPPY_SCRIPT_MAX_BYTES | 1073741824 (1 GiB) | The most bytes a shared script run may declare: the package and what its dependencies export. |
SHIPPY_SCRIPT_MAX_FILES | 50000 | The same in files. |
SHIPPY_SCRIPT_TIMEOUT | 1800 | Seconds a script's run on the box may take, waiting included, before it runs here. |
SHIPPY_MAX_SIZE | half of the store's size plus free space, at most 50GB | How large the local store may get, such as 50GB or off. |
SHIPPY_MAX_AGE | no limit | Also remove results not used for this long, such as 14d. |
SHIPPY_GC | 1 | 0 never cleans the store after a build. shippy gc still does. |
SHIPPY_GC_GRACE | 15m | How long what was just stored or used is left alone. |
SHIPPY_GC_INTERVAL | 10m | How often a build starts a cleanup round. |
Prefetch and upload
| Setting | Default | What it does |
|---|---|---|
SHIPPY_PREFETCH | 1 | 0 never fetches a build's results before cargo starts. |
SHIPPY_PREFETCH_JOBS | 16 | Connections a prefetch downloads over. |
SHIPPY_PREFETCH_MAX_BYTES | 20GB | The 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_TIMEOUT | 600 | Seconds a prefetch may take before cargo starts without the rest. |
SHIPPY_PUSH_JOBS | same as SHIPPY_PREFETCH_JOBS | Connections an upload sends over. |
SHIPPY_COMPRESS | automatic | 1 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.
| Setting | Default | What it does |
|---|---|---|
SHIPPY_EXEC | 0 | Which 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_JOBS | eight per core, at most 64 | Crates cargo works on at once while the box compiles. |
SHIPPY_EXEC_RECHECK | 0 | 1 compiles here as well when the box's compiler failed, and believes this machine's. |
SHIPPY_EXEC_TIMEOUT | 900 | Seconds a remote compilation may take, waiting included, before this machine compiles the crate. |
SHIPPY_EXEC_MAX_BYTES | 64 MiB, or 1 GiB for a downloaded package | The 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_FILES | 20,000, or 50,000 for a downloaded package | The same in files. |
SHIPPY_EXEC_INLINE | 4194304 (4 MiB) | The most bytes of inputs a request to compile brings with it. 0 sends nothing along. |
SHIPPY_LOCAL_JOBS | one per core | Compilers 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.
| Setting | Default | What it does |
|---|---|---|
SHIPPY_BROKER | 1 | 0 has every crate connect to the box itself. |
SHIPPY_BROKER_CONNECTIONS | 8 | Connections the crates of a build share for lookups and blobs. |
SHIPPY_BROKER_SOCKET | set by shippy, not by you | The broker's socket path. |
SHIPPY_BROKER_FOR | set by shippy, not by you | A digest of the remote and token the broker was started for. |
SHIPPY_TOKEN_HANDOFF | set by shippy, not by you | The 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.
| Setting | Default | What it does |
|---|---|---|
SHIPPY_FIXED | fixed_paths, else home | 1 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_WS | root, else the git repository around the workspace | The 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_INSIDE | set by shippy, not by you | Marks 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_HOME | set by shippy, not by you | The real directories behind the fixed ones. |
SHIPPY_AT_HOME | set by shippy, not by you | The cargo home a build was to have at its fixed place, for what the front end starts after cargo. |
Debug
| Setting | Default | What it does |
|---|---|---|
SHIPPY_DEBUG | unset | Set: the wrappers and the front end say more on stderr, such as why a step was skipped. |
SHIPPY_QUIET | unset | Set: no summary line after a build. |
SHIPPY_PROFILE | unset | Set: 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_CARGO | cargo | The program the front end runs in place of cargo. |
Internal
| Setting | Default | What it does |
|---|---|---|
SHIPPY_SESSION | set by shippy, not by you | Names the build, so its wrappers write one session log. |
SHIPPY_LOCAL_JOBSERVER | set by shippy, not by you | Names 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
- README.md:
shippy.tomland the switches - docs/operations.md: clients and
shippy setup - docs/remote-exec.md: the
SHIPPY_EXEC*settings - docs/build-scripts.md: which script runs are cached
- docs/broker.md: the broker