# Run your own CI

Codebahn's [hosted runners](/docs/ci-runners/) are available on both plans. If you want jobs to run on your own hardware instead, you have two options: register a Forgejo runner that polls Codebahn for jobs, or point an external CI system at your repositories.

If you have hosted runners and want to get started with a workflow file instead, see [Set up CI](/docs/set-up-ci/).

## Prerequisites

- A Codebahn account with a repository ([getting started](/docs/getting-started/))
- For BYO runner: Docker and the [forgejo-runner binary](https://code.forgejo.org/forgejo/runner/releases) on your machine
- For external CI: access to a running CI system (Woodpecker, Jenkins, etc.)

## BYO runner

A Forgejo runner polls Codebahn for jobs, executes them in Docker containers, and reports results back. Follow the [Forgejo runner installation guide](https://forgejo.org/docs/latest/admin/runner-installation/) for the binary, Docker, Podman, and systemd setup. This section covers what's specific to Codebahn.

### Connection config

Get a UUID and registration token from **Settings > Actions > Runners** (available at user, org, or repo level). Point the runner at Codebahn:

```yaml
server:
  connections:
    codebahn:
      url: https://codebahn.net/
      uuid: YOUR_UUID
      token: YOUR_REGISTRATION_TOKEN
```

:::caution
The registration token can be reused until you regenerate it. Register your runners, then generate a new token so the old one stops working.
:::

### Runner image

Use the Codebahn runner image to get the same environment as the hosted runners, including pre-cached Go and Node toolchains:

```yaml
runner:
  labels:
    - my-runner:docker://rg.fr-par.scw.cloud/codebahn-runner/ubuntu:24.04
```

Substitute any Docker image you prefer. See [CI runners](/docs/ci-runners/#what-the-image-ships) for the image contents.

### Job routing

`ubuntu-latest`, `codebahn-small`, `codebahn-medium`, and `codebahn-large` route to Codebahn's hosted runners. Use a distinct label to keep your own hardware separate:

```yaml
jobs:
  build:
    runs-on: my-runner
```

Reserved labels are rejected at registration and on every daemon start. If your runner's labels include a reserved one, it fails with:

```
labels ubuntu-latest are reserved for Codebahn-managed runners; remove them from this runner's labels
```

Jobs on your own runners are not metered: they never count against your compute minutes or top-ups. Running CI on your own runners still requires an active plan.

## External CI

If you already run Woodpecker, Jenkins, or another CI system, point it at your Codebahn repositories. You need two things: a clone token and a webhook.

### Clone token

Go to **Settings > Applications** and create an access token with the `read:repository` scope. Use it in your CI system's clone URL:

```
https://token:YOUR_TOKEN@codebahn.net/owner/repo.git
```

### Webhook

Add a webhook under **Settings > Webhooks** on your repository, pointing at your CI system's trigger URL. See [Webhooks](/docs/webhooks/) for payload verification and the full event list.

### Provider notes

- **Woodpecker CI** supports Forgejo natively. See [Woodpecker's Forgejo integration docs](https://woodpecker-ci.org/docs/administration/forges/forgejo) for server config. Create an OAuth2 application under **Settings > Applications** on Codebahn for the client credentials.
- **Jenkins** works via the clone token as a Git credential (username: `token`, password: your access token) and a webhook trigger.
- **GitHub Actions** works via a push mirror. Set one up under **Settings > Repository > Mirror Settings** on Codebahn; commits mirror to GitHub and run on GitHub's runners.

## Support boundary

:::note
BYO runners and external CI run on your infrastructure. We support the integration points and document the setup. If something goes wrong on our side, email us. If the issue is in your runner or CI system, that is yours to debug.
:::
