Search Composal documentation

Search public documentation, commands, and release notes.

GitHub Actions runners

Run GitHub Actions jobs on Composal. Choose VM or sandbox runners, use the included tools, or preload your own Docker image.

Contents

Use the included tools

Composal runners include Node 24, AWS CLI v2 and GitHub CLI (gh). Use them directly in your workflow steps. actions/setup-node or your project's tool manager can select another Node version.

Set up runner access

Install Vex 1.17.90 or newer to manage runners. Sign in and check the pools and images available to your organization:

Bash
curl -fsSL https://dl.composal.ai/install-vex -o /tmp/install-vex.sh
sh /tmp/install-vex.sh
vex login
vex --org acme runner github list
vex --org acme runner images list
vex agent-help

Your organization needs GitHub Actions runner access enabled and a GitHub App connection with access to the repository. Organization owners and administrators can configure images and pools. A pool serves one exact repository/label pair.

Choose a VM or sandbox

Workflow labelRuntimeChoose for
composal-vm-x64-4xVMDocker builds, container actions and service containers
composal-sandbox-x64-4xSandboxShell and JavaScript actions, lint and tests without Docker
composal-x64-4xVMExisting workflows; keeps VM behavior

Each label family offers 2x, 4x, 8x and 16x sizes, with 2/4/8/16 CPU cores and 4/8/16/32 GiB RAM. Sandboxes do not run a Docker daemon. Use a VM for container actions, service containers and Docker builds.

Configure a runner pool

Configure a pool to use the standard tools:

Bash
vex --org acme runner github configure acme/monorepo \
  --label composal-sandbox-x64-4x --default-image --max-concurrency 8

Then select that exact label in GitHub Actions:

YAML
jobs:
  check:
    runs-on: composal-sandbox-x64-4x
    steps:
      - uses: actions/checkout@v7
      - run: node --version && aws --version && gh --version

Mount dependency caches

Mount persistent storage at a package cache directory with a stable key:

YAML
- uses: composalai/disk-volume@v1.2.0
  with:
    key: npm-store-v1
    path: ~/.npm
- run: npm ci

Package managers use the mounted directory in place. The post step flushes writes; there is no archive restore, copy-back or automatic cache cleanup. The checkout, workspace and .git stay on local runner disk.

Keys are scoped to the GitHub installation and repository. Jobs with the same key share a writable cache across branches and runner sizes, including pull requests and failed jobs. Use download stores with package integrity checks, such as npm, pnpm and Cargo caches. Keep credentials and build outputs out of these directories. Choose separate keys for tools that require exclusive access.

The action accepts an empty absolute, workspace-relative or ~/ path, with up to five mounts per job. cache-hit: true means the directory exists; the package manager still installs missing dependencies. The first run after this storage update starts cold.

Preload your own tools

For additional tools or pinned dependencies, write a linux/amd64 Ubuntu 24.04 Dockerfile with Node 22 or newer on PATH. Custom images keep their own Node version. Keep credentials out of image layers. For example:

DOCKERFILE
FROM node:24-bookworm-slim AS node
FROM ubuntu:24.04
COPY --from=node /usr/local/ /usr/local/
RUN apt-get update && apt-get install -y ca-certificates curl git gh jq

Build and push it to your registry. Register the immutable digest printed by the push, replacing the placeholder with its real 64-character SHA-256:

Bash
docker buildx build --platform linux/amd64 \
  --tag ghcr.io/acme/actions-tools:v1 --push .
vex --org acme runner images create tools-v1 \
  --image ghcr.io/acme/actions-tools@sha256:<64-hex-digest> --wait
vex --org acme runner github configure acme/monorepo \
  --label composal-sandbox-x64-4x --image tools-v1

Composal prepares the image once, adding the Actions runner and its supporting tools. Preparation moves through pending and building, then ends at ready or failed. New runners reuse the prepared image. Composal replaces CMD and ENTRYPOINT, so put permanent setup in Dockerfile RUN instructions.

Pull from a private registry

Private registries use --registry-secret RUNNER_REGISTRY. This names an active organization secret exposed to CI whose JSON value contains exactly REGISTRY_USERNAME and REGISTRY_PASSWORD, both nonempty strings. Store the value using secret management with stdin or a private file. Composal uses these credentials to pull the image; it does not add them to workflow environments. Registration does not grant registry access.

Update tools or restore the defaults

Inspect preparation and retry a failed build:

Bash
vex --org acme runner images get tools-v1 --json
vex --org acme runner images prepare tools-v1
vex --org acme runner images wait tools-v1 --json

Ready images are immutable. Publish a new digest and image name to update tools. Images are scoped to their organization. Switching a pool affects new runners; running jobs finish on their original image. A pool waits for its selected image to become ready. Verify a real GitHub job receives a composal-gh-* runner, prints the expected tool versions, and reaches a terminal result.

Use --default-image to restore the standard toolchain. Omit both image flags to retain the current selection. Configuring a label does not rewrite workflows or disable other pools; each pool has its own concurrency limit.