tofupilot build
Last updated on November 9, 2026
The build command makes a procedure's deployment bundle on this machine, with the same steps as the cloud build. Use it when the build needs something only your network reaches, such as a private package registry. Ship the result with tofupilot deploy --prebuilt.
tofupilot buildThe directory must contain a pyproject.toml (a uv package, possibly a member of a uv workspace). Without uv.lock, build generates one and warns: commit it to make builds reproducible.
What a bundle holds
A bundle holds the procedure's source and every package it needs as a wheel. The station installs these files without reaching any package index, so it needs no credentials for your registry. Python and uv are not in the bundle: the station installs them as for any deployment, from dl.tofupilot.app.
Stations need CLI 2.13.0 or newer to install these bundles. The bundles go to .tofupilot/output/ in the procedure folder. That folder ignores itself in git, and each build replaces the bundles of the previous one.
Platforms
When every package is pure Python, one bundle serves every platform (deployment-standalone-universal.tar.zst). Otherwise build makes one bundle per platform, for this machine by default. --platform names the stations' platforms instead, and can be repeated: linux_x86_64, linux_aarch64, macos_arm64, windows_x86_64.
tofupilot build --platform linux_x86_64 --platform windows_x86_64Each bundle holds the packages its platform needs, as uv.lock describes them. A package with no published wheel for a platform is compiled here, which works for another platform than this machine's only when the package is pure Python. Otherwise the build fails and names the package: build on a machine of that platform, or pin a version that publishes a wheel for it.
Private registries
Each package is downloaded from the index uv.lock records for it. build knows the indexes declared in pyproject.toml, in the project's or your own uv.toml, and in uv's environment variables (UV_INDEX, UV_DEFAULT_INDEX, UV_INDEX_URL, UV_EXTRA_INDEX_URL). A registry that needs credentials gets the ones uv reads:
| Source | Example |
|---|---|
Environment variables, <NAME> being the index name uppercased, other characters replaced by _ | UV_INDEX_COMPANY_REGISTRY_USERNAME, UV_INDEX_COMPANY_REGISTRY_PASSWORD |
| Credentials written in the index URL | https://ci:token@pypi.example.com/simple/ |
~/.netrc | an entry for the registry's host |
export UV_INDEX_COMPANY_REGISTRY_USERNAME=ci
export UV_INDEX_COMPANY_REGISTRY_PASSWORD="$REGISTRY_TOKEN"
tofupilot buildCredentials stored by uv auth login or a keyring provider are not passed on. Use one of the sources above instead.
Git state
In a git repository, each bundle records the commit it was built from and whether the project had uncommitted changes. build lists those changes when there are some, and the deployment shows the commit with a modified badge. The tofupilot.json that tofupilot link writes counts as a change until you commit it or add it to .gitignore.
Limits
- A uv
flatindex (a folder or a page of wheel links) is not supported. - A bundle larger than 95 MB cannot be uploaded.
- A git or path dependency gets its build backend from PyPI, not from your registry.
- A package compiled from source on a musl Linux machine (an Alpine container) is refused: stations run glibc. Build on a glibc Linux machine such as Debian or Ubuntu.
--json
With --json, build prints one object typed "build": the runtime_version, the git state, and the artifacts, each with its path, platform (null for a bundle that serves every platform) and size_bytes.
How is this guide?
tofupilot batches
Manage TofuPilot production batches from the terminal to group units, track first-pass yield, and tie runs back to a manufacturing lot.
tofupilot config
Inspect the local TofuPilot CLI configuration including dashboard URL, station ID, terminal and kiosk UI modes, and runtime settings.