Toolchains the product installs
Reqursor Development installs the runtimes a ticket needs, such as PHP and Composer or Node.js, before the run starts. What it installs, from where, and how to add your own.
Some tickets need a runtime that the agent's sandbox does not ship, such as PHP and Composer for a Laravel project, or Node.js for a web app. Reqursor Development installs these runtimes itself, before the run starts, so a run that needs them just works. A developer can also add a toolchain of their own, with the same safety rules.
The install is on by default, on every install. An Owner, Admin or Developer can switch it off in Settings → System, on the Toolchains card. When it is on, the product downloads pinned toolchains from the vendor hosts listed below, and from nowhere else.
What is installed
| Toolchain | What you get |
|---|---|
| PHP and Composer | php and composer (Composer is always installed with PHP) |
| Node.js | node, npm, npx and corepack |
| Go | go and gofmt |
| Java | A Temurin JDK with java and javac, and Maven with mvn |
| Your own | Anything a developer adds, see "Add your own toolchain" below |
The agent's image also carries the everyday basics (make, gcc, g++, unzip, curl, jq and
Node.js with npm), so a small Node job needs no download at all.
Node.js, PHP and Composer come preinstalled. The worker installs them in the background as soon as it starts, and again when someone switches the install on, so the first Node or PHP ticket never waits for the download and the Toolchains card shows them as installed. They are downloaded on the first start, not carried in the release, so the install needs that connection once. The other toolchains are installed when a ticket needs them.
What happens
Before a run starts, the worker works out what the ticket needs. It looks at:
- the files in the repository, in the root and one folder down (for example
composer.json,package.json,go.modorpom.xml), - the words in the ticket (PHP, Laravel, npm, Maven and so on),
- the first word of your check commands (
php,npm,go,mvnand so on), - for a custom toolchain, the file names and words its author named, and its command names.
If something is missing, the worker installs it once into a shared toolchain location and puts it on
the PATH of every command in the run: the agent's tools, the checks and your check commands. A run
that needs nothing adds no delay and downloads nothing. The run log records toolchain_ready when
the tools are there, or toolchain_failed with one plain sentence when they are not. A failed
install never fails the run: the agent then stops with ENVIRONMENT BLOCKED: and the ticket waits
for you, as described in Missing toolchain vs. a real failure.
An install is shared. The first run that needs a toolchain installs it, and every later run, in every project, uses the same copy.
What is downloaded, and from where
When the install is on, the product contacts these hosts for the built-in toolchains, and nothing else:
| What | Host |
|---|---|
| PHP | dl.static-php.dev, and static-php-cli.fra1.digitaloceanspaces.com for its redirects |
| Composer | getcomposer.org |
| Node.js | nodejs.org |
| Go | go.dev, which redirects to dl.google.com |
| Java (Temurin) | github.com, which redirects to release-assets.githubusercontent.com |
| Maven | archive.apache.org |
| Package metadata for Composer | repo.packagist.org |
| Package archives for Composer | codeload.github.com, api.github.com, gitlab.com, bitbucket.org, packagist.org |
Your code and your ticket text are never sent to these hosts. The worker only asks for the tool
itself, or for the package that your own composer.json or composer.lock names. A custom toolchain
contacts the host its author typed, and only when it is installed.
Safe by design
- The product installs, the agent never does. Only the product's own process downloads. The agent cannot start an installer, so a run adds no new way for an agent to pull software in.
- Fixed versions and checksums. Each built-in tool is pinned to one version and to the SHA-256 checksum of its download, written into the product. A checksum is never read from the network, and a download that does not match installs nothing.
- Proven in isolation. After unpacking, the product starts the tool once to prove it runs. That happens inside the isolated runner, with no network.
- Read-only for commands. The toolchains are mounted read-only where the agent's commands run, so nothing a command does can change an installed tool.
- Audited. Every install, every failed install, every change of the switch and every custom toolchain added or removed is an entry in the audit log, with who made it. The log names the tool and its version, never the download address.
Packages that live on GitHub
Composer downloads many packages from GitHub, and GitHub stays blocked for the agent and for every
check command on purpose, so an agent cannot use it as a way out. To let composer install work
anyway, the product runs a small read-only archive gateway for each run:
- It answers only
GETrequests, and only for package archives named by the package registry (Packagist) information that the worker fetched itself. - It never forwards a request that the agent wrote: no uploads, no API writes, no git.
- Each redirect is checked against the same host list, and an archive is capped at 200 MB.
The list of hosts that commands may reach does not change: it still names no git host and no model provider.
Who can do what
| Role | See the toolchains | Switch the install, add, install and remove custom toolchains |
|---|---|---|
| Owner | Yes | Yes |
| Admin | Yes | Yes |
| Developer | Yes | Yes, no Owner needed |
| Viewer | Yes | No |
Add your own toolchain
Use this when a project needs a runtime that is not built in, such as .NET or Bun. Open Settings → System, find the Toolchains card and choose Add Toolchain. The product checks every rule below, not you.
- Find a download. You need an
httpsaddress of a Linux build that fits the machine your install runs on. The file can be atar.gz, atar.xz, azipor a single program file. - Fetch the checksum. Paste the address and choose Fetch Checksum. The product downloads the file once, under the safety rules below, and shows the SHA-256 checksum, the size and the host. It keeps nothing and installs nothing.
- Check it yourself. Compare the checksum with the one the publisher lists, or with a copy you trust. The product never accepts a checksum from the network on its own: you confirm it (This is the file I mean to install) in the next step.
- Fill in the rest.
- Name: lowercase letters, numbers,
-and_, starting with a letter. It cannot be the name of a built-in toolchain. - Version: letters, numbers and
.,_,+,-. - Archive kind and Folders to skip: the file type (
tar.gz,tar.xz,zipor a single file) and how many leading folders to drop when unpacking (0 to 5, most archives need 0 or 1). - Command name and Path inside the archive: each command name and where its program is
inside the package, as a relative path such as
bin/dotnet. A single file provides one command. - Test command: a short command that proves the tool starts, such as
dotnet --version. It must start with one of your command names. - Install it when a ticket mentions and Install it when the repository has these files (both optional): words and file names, separated by commas, that tell the product a job needs this tool. The command names always count too.
- Name: lowercase letters, numbers,
- Add it. The product starts the install in the background. The card shows Installing, then Installed, or Failed with one plain sentence. Choose Install now to try again.
- Use it. A job installs the tool on demand when the ticket, the check commands or the repository match its detection rules or its command names. A tool whose last install failed is not retried by jobs; choose Install now instead.
To remove a custom toolchain, choose Remove on its row. The product deletes its files.
The safety rules for a custom toolchain
- https only. No other scheme, no user name or password in the address, and no port except 443.
- Public addresses only. The product looks up the host itself, and every answer must be a public internet address. A private network, a loopback address, the cloud metadata address or a name that resolves to any of them is refused, and so is a name with a mix of public and private answers. This is checked again on every redirect.
- No switching addresses. The connection goes to the address that was checked, not to the name, so the name cannot point somewhere else between the check and the download. The certificate is still checked against the host's name.
- Limited redirects. At most 5, and only to the same host.
- Limits. A download is capped at 400 MB and 10 minutes. No cookies and no credentials are sent.
- Your checksum. The download must match the checksum you confirmed, or nothing is installed.
- Safe unpacking. A package with a path that escapes its folder, an absolute path or a link that points outside is refused.
- No overwriting. A custom toolchain never replaces a built-in command, and never replaces a command that already exists.
- At most 25 custom toolchains per install.
- A checked probe. The tool has to start inside the isolated runner, with no network. If an install has no isolated runner, a custom toolchain is refused instead of being started on the worker. The Docker Compose install has one.
- Off means off. With the switch off, nothing is downloaded, not even the checksum step.
Turn it on or off
Open Settings → System and use the switch Install the runtimes a ticket needs on the Toolchains card. Switching it off stops new downloads. Tools that are already installed stay, are listed on the card and keep working. The same switch turns it on again.
Where it lives
- Docker Compose: a volume named
toolchains, mounted at/opt/toolchains. The worker and the web app can write it; the runner mounts it read-only. Back it up like any volume, or leave it out: the next run that needs a tool installs it again. - Bare metal and Windows: the folder
toolchainsinside the data directory.
To remove a built-in tool, switch the feature off and delete that volume or folder. The next run that needs it installs it again once the switch is on.
Troubleshooting
| Message | What it means |
|---|---|
toolchain_failed with a checksum sentence | The download did not match the checksum, so nothing was installed. For a built-in tool, try the run again later; if it repeats, tell support. For a custom tool, check the address and fetch the checksum again. |
toolchain_failed with a time sentence | The install took longer than 15 minutes, so the run started without it. |
ENVIRONMENT BLOCKED: and no toolchain entry at all | The switch is off, or the ticket and the repository did not look like they need a runtime. Switch it on, or name the tool in the ticket. |
| "That command already exists." | A custom toolchain tried to use a command name that a built-in tool or another toolchain already has. Pick another command name. |
| "points to a private or local network" | The host of a custom download resolves to an address that is not on the public internet. Use a public host. |
| "was interrupted by a restart" | The install was running when the web app restarted. Choose Install now. |
| "cannot be checked safely on this install" | There is no isolated runner to prove the custom tool starts. Use the Docker Compose install. |
- Missing toolchain vs. a real failureWhat happens when a tool is still missing.
- Auto-detected checksThe checks that use these tools.