Skip to content

CI runners

Every plan includes hosted CI runners. Jobs with runs-on: ubuntu-latest route to them automatically. To add your first workflow and watch it run, follow Set up CI. This page is the reference: sizes, image contents, compatibility, and bringing your own hardware.

Hosted runners run on Scaleway instances in the EU (Paris, fr-par). Every plan can use any size. Pick the size with the runs-on label:

LabelSpecCost factor
codebahn-small3 vCPU, 4 GB1x
codebahn-medium4 vCPU, 8 GB2x
codebahn-large4 vCPU, 12 GB3x

ubuntu-latest is an alias for codebahn-small.

Larger runners consume compute minutes faster according to their cost factor. A 5-minute job on codebahn-medium (2x) uses 10 compute minutes.

Each job runs in an isolated, ephemeral VM with no state carried between runs. A cold start takes about 40 seconds from push to a running job. A second job landing on a warm runner starts in about 2 seconds. Compute minutes are wall-clock multiplied by the cost factor, hard-capped per plan, and toppable; see Set up CI for how counting and top-ups work, and Limits for the caps.

The image follows the GitHub Actions runner layout. It carries common build tools (git, curl, build-essential, the Docker CLI) and a system Python, plus pre-cached Go and Node toolchains in the GitHub-style toolcache so actions/setup-go and actions/setup-node resolve offline and instantly.

ToolchainPre-cached major versions
Go1.25, 1.26
Node22, 24, 26
steps:
- uses: actions/checkout@v4
- uses: actions/setup-go@v5
with:
go-version: "1.26"
- run: go build ./...

Other Go and Node versions still work; setup-go and setup-node fetch them at job time.

Not pre-installed: cloud provider CLIs, browsers, databases, and other language runtimes. If you need one, install it in your workflow:

- run: sudo apt-get update && sudo apt-get install -y sqlite3
- uses: actions/setup-python@v5
with:
python-version: "3.13"

Runners reach package registries and download hosts over HTTPS and DNS only. Other egress is blocked: SSH-based git fetches, services on non-standard ports, and the cloud metadata endpoint (169.254.0.0/16). Fetch private dependencies over HTTPS.

Codebahn runs Forgejo Actions, which implements the GitHub Actions workflow syntax. Most .github/workflows/ files run unchanged, and actions/* resolve from GitHub by default, so uses: actions/checkout@v4 works as-is.

Some things do not run:

  • macOS and Windows jobs. Hosted runners are Linux only.
  • OIDC token federation, GitHub code scanning, and GitHub Pages. These depend on GitHub-only services.

.gitlab-ci.yml files are not read. A new commit to the same branch auto-cancels in-progress runs on that branch; override with a concurrency block if you need runs to finish.

For the workflow syntax itself, see the Forgejo Actions reference.

Register your own hardware alongside the hosted runners. Jobs route to it by exact label match. Your machine needs Docker and the forgejo-runner binary.

In your org, go to Settings > Actions > Runners and generate a registration token.

Create config.yml with your connection details and a distinct label:

server:
connections:
codebahn:
url: https://codebahn.net/
uuid: YOUR_UUID
token: YOUR_REGISTRATION_TOKEN
runner:
capacity: 4
timeout: 3h
labels:
- my-runner:docker://rg.fr-par.scw.cloud/codebahn-runner/ubuntu:24.04
container:
docker_host: unix:///var/run/docker.sock

The Codebahn runner image (rg.fr-par.scw.cloud/codebahn-runner/ubuntu:24.04) gives you the same environment as the hosted runners, including the pre-cached Go and Node toolchains. Substitute any Docker image you prefer.

Terminal window
forgejo-runner daemon -c config.yml

For production, run this under systemd or an equivalent supervisor. The runner polls for jobs and executes them in Docker containers.

Use the label from your config in the workflow:

jobs:
build:
runs-on: my-runner

ubuntu-latest, codebahn-small, codebahn-medium, and codebahn-large go to the hosted runners. A distinct label keeps your own hardware separate.

For BYO runner setup and external CI alternatives, see Run your own CI.