Runner Labels
As an alternative to using profiles, you can keep the entire runner configuration version-controlled within your workflow file. This works by specifying one or more labels in theruns-on configuration of your workflow.
Machine Label
The most important label is the one selecting architecture, operating system, and machine shape. The label looks likenscloud-{os}-{arch}-{shape}
Note: only one nscloud label is allowed in the
runs-on field of your workflow file. Namespace will not schedule any
workflow job if runs-on
specifies more than one nscloud label or invalid ones.
Supported machine labels per OS
Machine label suffixes
A machine label can be extended with one or more-with-* suffixes to enable extra capabilities on the runner,
without changing its shape:
nscloud-{os}-{arch}-{shape}[-with-cache][-with-features][-with-builders]
For example, nscloud-ubuntu-24.04-arm64-32x64-with-cache selects an Ubuntu 24.04, arm64, 32x64 machine with a cache
volume attached. Suffixes can also be chained to combine capabilities on a single runner, as shown below.
Combining cache and features
To request more than one capability on a single runner, chain the suffixes on the machine label. Order does not matter, and any companion labels are listed as separate entries. For example, a runner that has a cache volume and also runs privileged:-with-cache attaches the cache volume (sized and tagged by the
nscloud-cache-* companion labels) and -with-features enables the settings
passed in the namespace-features: label.
Configuring Features and Overrides
Beyond selecting a machine shape or profile, you can pass additional feature settings and overrides to a runner, for examplecontainer.privileged,
github.run-id, or tailscale.spec.
How you pass them depends on whether you use runner labels or a runner profile.
- With runner profiles
- With runner labels
The
namespace-features: label cannot be used with profiles. Instead,
append one or more ;key=value pairs directly to the profile name:Cache Volumes using Runner Labels
Using a Cache Volume
- With runner profiles
- With runner labels
If you configured a runner profile using the web UI and use
namespace-profile-name runner label, enable caching by simply going to the runner profile and enabling caching.Cache volumes also enable caching for built-in software (Git, containerd, toolchain).You can also force a custom cache tag. This allows sharing a cache from multiple profiles or repositories:Example: Caching NPM Packages
Use ournscloud-cache-action to mount the volume
under the paths you want to cache.
- With runner profiles
- With runner labels
Caching Docker Images Across Invocations
Namespace also makes it trivial to cache container image pulls (and unpacks, often the most expensive bit) across invocations.- With runner profiles
- With runner labels
To enable this feature, just open the runner profile configuration, add a cache volume and enable
Container images.Known incompatibilities for Docker Image caching
Docker image caching relies on standard Docker APIs. However, if you are using a tool that does not fully support Docker APIs, Docker Image caching can break your workflow. Known issues are:- Spring Boot does not provide full image spec compatibility in their Buildpacks plugin
Caching GitHub Tools
Namespace volumes can cache GitHub tools across invocations. For example,actions/setup-go and actions/setup-python
actions first look for their binaries in
$RUNNER_TOOL_CACHE directory, before fetching
from remote.
- With runner profiles
- With runner labels
To make GitHub tool cache use Namespace volumes, open the runner profile configuration, add a cache volume and check
Toolchain downloads.Caching Git Repositories
With cache volumes, you can set your GitHub workflow to cache large git repositories to speed up the checkout phase. After you enabled the Git caching (see below how), you’ll need to change your workflows to call our optimized checkout action, which will make use of the cache volume to store and retrieve the git mirrors. See thenscloud-checkout-action
page for more details.
- With runner profiles
- With runner labels
To enable this feature, just open the runner profile configuration, add a cache volume and check
Git repository checkouts.Expected Use Cases
Note that thenamespacelabs/nscloud-checkout-action is optimized to speed up only specific use-cases.
If your workflows do not belong to these, you might not see the expected performance improvement.
- Very large repositories: when the workflow needs to check out a repository with many or big files.
- Checkout long commits history: when the workflow needs to check out many commits (the default is only 1).
- Repositories with a large set of submodules.
- Repositories with Git LFS objects.
Custom Cache Identity
For scenarios requiring full control over the cache isolation boundary, you can specify custom cache tags.- With runner profiles
- With runner labels
To specify a custom cache tag when using a profile, append
;overrides.cache-tag=new-tag-value to the profile name:Advanced: Protect Caches from Updates
You can configure Cache Volumes to limit what git branches can perform updates to them. This configuration allows you to use the same cache as the main branch from other branches (e.g. pull requests), but not commit changes to it.- With runner profiles
- With runner labels
To specify which branches can update the cache volume, open the cache volume configuration, then check
Show Advanced features, and finally type the branch names.Manage Cache Access per Job
Instead of protecting your cache per branch, you can also select which jobs may write to the cache. This allows you to share a cache amongst multiple jobs while some are not allowed to update the cache contents. Any job without commit rights can still access the cache and can also change contents locally. But any edits that it makes to the cache will be ignored for future runs. If using runner labels, you can add the labelnscloud-cache-exp-do-not-commit to a job.
Controlling Job Order
By default, there is no queuing or ordering for jobs: as soon as a job is scheduled a runner is started for it. This changes when your workspace is hitting concurrency limits and jobs have to wait for resources to become available. Namespace offers controls to influence the order of jobs to be picked up:Deterministic assignments
By default, a job can be assigned to any runner that matches that job’s labels. A runner will pick up the job that it’s assigned by GitHub, which does not happen in order. This means that while hitting concurrency limits, jobs with the same labels might not be executed in the expected order. To control this behaviour, you can add the run id to the labels. Then only that specific job can be picked up by the runner started for it, and jobs are executed in the order in which they are scheduled:- With runner profiles
- With runner labels
Job Priority
When some workflows should not be blocked by other less, time-sensitive ones, you can assign them a priority. Priority only affects scheduling while running into concurrency limits. Pending jobs with the lowest numbers will be started first. Jobs with any priority specified take precedence over those without. To specify a priority, appendjob.priority=<number> to the runs-on label:
- With runner profiles
- With runner labels
Namespace Remote Builders
Building very large images
For most users, relying on Remote Builders is the preferred option.
- With runner profiles
- With runner labels
To enable this feature, just open the runner profile configuration and add a cache volume. Next, select
Locally cached for your Docker builds.Caveats
- Build caching using “local caching” is not shared with Remote Builders; each repository uses its own separate cache.
- Although multi-platform builds are supported, only builds of the same platform as the runner itself, will experience native performance.
Large amounts of concurrent builds
Namespace Remote Builders are configured to offer great performance for many concurrent builds. These defaults provide ideal performance for most customers. If you run a very large amount of concurrent builds, please reach out to support@namespace.so and we’ll scale your Remote Builders to match your needs.Builds without output
When you want to test a build without pushing or loading it, use thecacheonly output type.
This runs the full build and populates the cache, but skips the export step:
Disable Build Caching
If you prefer to skip build caching altogether, you have two options:-
Revert the Docker build context to the default: Namespace configures Remote Builders
as a separate
buildxcontext. Before invoking a build that should not be cached, you can switch back to the default by callingdocker buildx use default. E.g. - Disable Remote Builders: You can request that runners created for a particular workflow job do not use Remote Builders.
- With runner profiles
- With runner labels
To disable remote builders, just open the runner profile configuration and select
No caching for your Docker builds.Privileged workflows
Namespace Runner Instances run the runner software itself in a container. This approach facilitates software packaging and enables custom base images. If your workflow requires deeper access to the host system, Namespace can run your workflow as privileged and in the host pid namespace. A common case that requires this is modifying kernel settings using sysctl. Another case is tooling that creates its own mount or user namespaces, such as bubblewrap (bwrap), which some sandboxing and Nix workflows rely on.
Without privileged mode these tools fail with an error like pivot_root: Operation not permitted. Enabling container.privileged resolves it.
To do so, enable the corresponding features in your runner labels:
- With runner profiles
- With runner labels
To make the runner container privileged append the feature
container.privileged. Similarly, you can select the host pid namespace with container.host-pid-namespace.Setting up Swap Space
Runners come without swap by default, when a job runs out of memory one or more process get terminated by the out-of-memory killer. Adding a swap file lets the kernel page cold memory out to disk, which can carry a job past short memory spikes without moving to a larger shape.- With runner profiles
- With runner labels
You can configure swap directly in the profile editor under
Advanced Settings.Connecting to Tailscale
To connect a runner to your Tailscale tailnet, reference a named Tailscale spec with thetailscale.spec feature. You
must first create that spec with nsc integrations tailscale set; the feature value is the spec name (for example
corp).
- With runner profiles
- With runner labels
Access Level
Each runner profile can declare an Access Level that controls which Namespace features the runner workload is allowed to use at runtime. Access levels apply on top of any explicit workload permissions configured on the workspace, and let you tighten what a particular runner can do without changing your workspace defaults. Access Level is a profile-only setting and is configured in the runner profile editor underAdvanced Settings.
Three levels are available:
- Permissive (default): the runner workload uses the workspace’s standard Namespace permissions. This is the historical behavior and the right choice for most profiles.
- Limited: the runner workload is restricted to the features needed by GitHub Actions jobs, including remote builders, the container registry, the cache service, and federated tokens. Other Namespace APIs are not reachable from the runner.
- Restricted: Namespace feature access is disabled for the runner workload. Use this for jobs that should not be able to call any Namespace APIs from inside the runner (for example, when running fully untrusted third-party code).
Systemd
Namespace Runner images by default do NOT use Systemd. For some users this might require small changes to their workflows, e.g. replacingsudo systemctl start ...
with
sudo service start ....
If your workflows rely on systemd, an image using systemd is available upon request.
Running Jobs in Containers
Namespace Runners support using custom containers for GitHub Jobs.Accessing Namespace resources from Containers
To access Namespace resources from within a container, extra configuration is required. In particular, the directory/var/run/nsc/ must be mounted into the container, and namespacelabs/nscloud-setup needs to be run.
See the following snippet for a working example of accessing Bazel:
Accessing Cache Volumes from Containers
To access Cache Volumes from within a container, additional configuration is required. For example, when using an Ubuntu-based custom image, the following snippet provides a working, minimal example:Accessing Git Mirrors from Containers
If your workflow runs in a container, additional configuration is required to use cached Git Repositories:Using Local build caching from Containers
While Remote Builders provide the best performance for most scenarios, in-runner builders (locally cached) excel when building massive images (10GB+). Keeping the build local skips network transfer time. To access in-runner builders from within a container, additional configuration is required.Enable local build caching
- With runner profiles
- With runner labels
To enable this feature, just open the runner profile configuration and add a cache volume. Next, select
Locally cached for your Docker builds.macOS Features
Bleeding-edge Images
Namespace team continuously makes changes to macOS runner images to keep the software up-to-date and add new Xcode versions as soon as Apple releases them. More info on image updates. To avoid regressions upcoming images go through multiple release stages before production release. This means that new Xcode versions become available to most customers with a short delay. However, it is possible to take advantage of new Xcode versions early. You can enroll your runners into using bleeding-edge macOS images. Note: Images in the bleeding-edge channel have not passed the full set of validation checks and may contain regressions. We are happy to hear feedback from early users of these images via Namespace support channels. But enrolling should be done without expectation of perfect stability.- With runner profiles
- With runner labels
Visit the runner profile editor and select the Use bleeding-edge images checkbox.