Skip to content

Admin guideBuilds

Language versions and toolchains

Which interpreters an install offers, how an app picks one, and how to retire a version.

View as Markdown

Toft ships no list of language versions. You install interpreters on the machine (or in the runner images); Toft probes for them and offers what it finds. A new Python needs no Toft release.

Admin → System info and the health endpoint list what was found. Run checks on Admin → System checks re-probes a family reported absent, so a newly installed interpreter shows up without a restart.

Four families, three versions each, highest first. The first entry is the family’s default.

Family In gopanair/toft Default
Python 3.15, 3.14, 3.13 3.15
Node 24, 22, 20 24
Go 1.27, 1.26.9 1.27
R 4.6, 4.5, 4.4 (Posit builds, /opt/R/<version>) 4.6

Quarto 1.10.19 is in the same image. Python 3.12 and R 4.3 are not offered: an app pinned to either is refused at its next deploy and keeps running until then.

  • Comparators only, never a patch version. 3.13.4 is refused, not truncated.
  • Refused, never approximated. A version you do not have fails the deploy before the build starts, listing what exists.
  • One declaration per family. Go’s is go.mod. A Posit Connect manifest.json is translated into an renv.lock.

There is no [runtime] go key and no RUNNER_GO_VERSION: go build produces a binary, so no Go reaches a runner. The go directive in go.mod is a minimum, and Go always takes the newest toolchain present — a toolchain line cannot hold a build on an older one.

To hold builds on a known toolchain, set GOTOOLCHAIN=go1.X.Y in the platform’s environment. It is on the build allow-list, and Go finds the matching toolchain on PATH before trying the module proxy, so it works with no egress.

Topic Behavior
Package repository TOFT_R_REPOS, default Posit Package Manager latest for Debian trixie. The largest lever on R build time; pin a dated snapshot if your estate needs reproducibility.
renv cache On, under CACHE_DIR/renv, and packages are copied out of it into the release rather than linked, so a release still travels. A package compiled from source is compiled once per version rather than on every deploy. Source compiles use every CPU unless the app sets MAKEFLAGS.
Library stamp A library records the R series it was built for; restoring a 4.5 library into 4.6 is refused.
System libraries pandoc and whatever your packages link against come from the machine or image.

Every build records the version it resolved, and both launchers start the workload under that version — a restart keeps it.

  • Admin → System info → Apps by language — the estate, counting the serving deployment, patch folded away.
  • The app’s Runtime section — one app, with the patch.
  1. Check Admin → System info → Apps by language for apps on it.
  2. Tell their owners, with a date.
  3. Remove the interpreter.

Running apps keep running; a restart restores the same deployment. The app’s next deploy is refused with the list of versions that exist.

Builds fetch from what the platform’s environment names: NPM_CONFIG_REGISTRY, UV_INDEX_URL, GOPROXY, and credentials for an authenticated mirror.

  • Prefer a credential variable over a token in a registry URL; a URL credential appears in build output.
  • Go and R have no credential variable — mount a netrc file.
  • GOOS and GOARCH are never passed through; a Go app that sets them is refused.