CI on Codeberg: hosted Forgejo Actions, ci.codeberg.org and your own runners

Codeberg gives you four ways to run CI: its hosted Forgejo Actions runners (small, time-limited, for public free-software projects), its Woodpecker CI instance at ci.codeberg.org (approval required), your own Forgejo Runner connected to a codeberg.org repository, user or organization, or your own Woodpecker agent attached to ci.codeberg.org. This guide shows when each one fits and how to set up the self-hosted options.

The four CI options at a glance

OptionWho runs the hardwareAccessGood for
Hosted Forgejo ActionsCodebergPublic, free-licensed repos; enable ActionsLinters, short test suites
Woodpecker at ci.codeberg.orgCodebergRequest form, manual approvalLonger builds on amd64
Your Forgejo RunnerYouAny repo you administerHeavy builds, arm64, GPUs, private repos
Your Woodpecker agentYouApproved ci.codeberg.org usersExtra architectures, hardware tests

Codeberg runs on Forgejo, so Forgejo Actions is the GitHub-Actions-style option and lives in .forgejo/workflows/. Codeberg's docs ask you to search and ask for help under the name "Forgejo Actions", since Codeberg runs the stock Forgejo feature.

Picking one

  • Your checks finish in under ten minutes on amd64 and the project is public and free-licensed: start with the hosted codeberg-small label. No setup beyond enabling Actions.
  • You already write GitHub Actions workflows and need longer jobs, private repositories, Docker builds or arm64: run your own Forgejo runner. The workflow files stay the same; only runs-on changes.
  • You prefer Woodpecker's container-per-step model and a pipeline file without the Actions marketplace: request ci.codeberg.org access, and add your own agent when the shared amd64 agents get too slow.

You can mix them in one repository. A common split puts linting on codeberg-tiny and the full test matrix on a self-hosted runner, so contributors get fast feedback and the heavy work stays on your hardware.

Codeberg's hosted Forgejo Actions runners

Codeberg's actions/meta repository documents the hosted runners. Codeberg calls them production-ready and enforces tighter resource and time limits than on Woodpecker, because hosted Actions has no approval step. Current labels:

LabelArchCPURAMMax runtime
codeberg-tinyamd6412 GB2 min
codeberg-smallamd6424 GB5 min
codeberg-mediumamd6448 GB10 min

Append -lazy (for example codeberg-small-lazy) if your job can wait; Codeberg schedules lazy jobs by load or energy availability and aims to finish them within 24 hours. Other rules:

  • The project must be public and under a free/libre license.
  • RAM includes files written to disk; Codeberg adds 2 GB of extra temp storage per container.
  • The default image is ghcr.io/catthehacker/ubuntu:act-latest.
  • Running a Docker daemon inside these runners is not supported. Codeberg points to Podman/Buildah for image builds.
  • Fair use: don't jam the queue, and use only the resources you need.

To use them, open your repository's Settings, Units, tick Enable Actions, and target a label:

# .forgejo/workflows/lint.yml
on: [push, pull_request]
jobs:
  lint:
    runs-on: codeberg-tiny
    steps:
      - uses: actions/checkout@v4
      - run: make lint

Woodpecker CI at ci.codeberg.org

Codeberg also runs a Woodpecker CI instance. Access is manual to protect volunteer-run hardware:

  1. Read the criteria your project must meet.
  2. Submit the Woodpecker access request.
  3. Once a volunteer approves it, log in to ci.codeberg.org with your Codeberg account.
  4. Enable repositories at https://ci.codeberg.org/repos/add.

Codeberg's caveats: Codeberg provides the service as-is and it can break at any time; resource use must be reasonable; Woodpecker's limited RBAC can get in the way of team-based permissions; and linux/amd64 is the only build target on the shared agents. Pipelines live in .woodpecker.yaml or .woodpecker/*.yaml.

Attach your own Forgejo runner

A self-hosted Forgejo Runner can serve a codeberg.org repository, your user account or an organization. It connects out to Codeberg and needs no public IP, so a home server works. Your jobs can run on private repositories too, since the free-license rule applies to Codeberg's hosted runners.

Create the runner on Codeberg

  1. Enable Actions in the repository (Settings, Units, Overview). Codeberg ships it disabled.
  2. Open Settings, Actions, Runners in the repository, organization or user settings.
  3. Click Create new runner, give it a name, and copy the UUID and token Codeberg shows.

Offline registration with forgejo-cli does not work here, because it needs admin access to the Forgejo server.

Configure the runner

Install forgejo-runner as described in the Forgejo runner guide, generate a config, then add a Codeberg connection with its own labels:

server:
  connections:
    codeberg:
      url: https://codeberg.org/
      uuid: <uuid from Codeberg>
      token_url: file:$CREDENTIALS_DIRECTORY/token.txt
      labels:
        - my-amd64:docker://docker.io/library/node:lts-trixie
forgejo-runner daemon -c /home/runner/runner-config.yml

Use label names that do not collide with codeberg-*, then target them in your workflow with runs-on: my-amd64. The runner config notes that Forgejo Runner may enforce a minimum fetch_interval for instances like Codeberg, so expect a few seconds of pickup delay. With the OCI image the setup is the same: mount runner-config.yml into data.forgejo.org/forgejo/runner:13 and give it a dind sidecar for Docker builds.

Attach your own Woodpecker agent

Approved ci.codeberg.org users can add agents to their user or organization. An agent belongs to one user or one org.

  1. Users: open https://ci.codeberg.org/user/agents. Orgs: open any org repo on ci.codeberg.org, click the org name, then settings, then the Agents tab.
  2. Click Add agent, name it, and copy the token.
services:
  woodpecker-agent:
    image: woodpeckerci/woodpecker-agent:v3
    command: agent
    restart: always
    volumes:
      - woodpecker-agent-config:/etc/woodpecker
      - /var/run/docker.sock:/var/run/docker.sock
    environment:
      - WOODPECKER_SERVER=grpc.ci.codeberg.org:443
      - WOODPECKER_AGENT_SECRET=${WOODPECKER_AGENT_SECRET}
      - WOODPECKER_GRPC_SECURE=true
      - WOODPECKER_AGENT_LABELS=location=region-1
volumes:
  woodpecker-agent-config:

Route workflows to it with labels: in the pipeline (for example platform: linux/arm64 or location: region-1). The Woodpecker agents guide covers backends, labels and autoscaling in depth.

Security on a public forge

  • Anyone on Codeberg can fork a public repository and open a pull request. Forgejo asks for approval on a contributor's first fork PR only; later PRs run without it. Run fork PRs on docker labels and never on host labels.
  • Register the runner at repository scope unless you need it across an org.
  • Store the token outside the config with token_url and systemd credentials, and keep container.privileged: false.
  • The Woodpecker agent above mounts the host Docker socket, which gives pipelines root-equivalent access to that host. Run it on a dedicated VM.
  • Put the runner on a network segment that cannot reach your home or office machines.

Troubleshooting

The Actions tab is missing

Codeberg ships Actions turned off for each repository. Enable it under Settings, Units.

Job queued but never starts on codeberg-*

Check the actions/meta status badges for queue health, or move the job to a -lazy label or your own runner.

Job killed after 2, 5 or 10 minutes

You hit the runtime limit of the hosted label. Move up a size or to a self-hosted runner.

Out-of-memory with small builds

Temp files count against RAM on hosted runners. Write less to disk or use your own runner.

Woodpecker agent shows offline

Verify WOODPECKER_GRPC_SECURE=true, the server grpc.ci.codeberg.org:443, and that the token belongs to the right user or org.

Cost trade-offs

Codeberg's hosted CI costs you nothing in money but caps runtime and size, and Codeberg funds it through donations. Self-hosted runners remove those caps and cost a VM or a home machine plus upkeep. Consider a donation to Codeberg e.V. if you lean on their CI.

FAQ

Does Codeberg have free CI?

Yes, for public free-software projects: hosted Forgejo Actions runners with fair-use limits, and Woodpecker CI after an access request.

Can I use GitHub Actions workflows on Codeberg?

Yes, with small changes. Put them in .forgejo/workflows/ and change runs-on to a Codeberg or self-hosted label. Forgejo documents the differences from GitHub Actions.

Can I build Docker images on Codeberg CI?

Not with a Docker daemon on the hosted Actions runners; use Podman/Buildah there, or your own runner with a dind sidecar.

Can I run arm64 CI on Codeberg?

Hosted runners are amd64 only. Attach your own arm64 Forgejo runner or Woodpecker agent.

Managed runners with cirunner.dev

cirunner.dev provisions a fresh VM per job, registers it with your CI using a token you provide, scales with the queue and destroys the machine after the job. You choose CPU, RAM, x86_64 or arm64, region, base image and an optional GPU, and pay per compute minute.

The service is in early access with GitHub Actions and GitLab CI at launch. Codeberg is on the roadmap; vote for it on the early-access form.

Skip the runner fleet

cirunner.dev boots a fresh VM for every Codeberg job, registers it, and destroys it when the job ends. Codeberg is on our roadmap. Vote for it on the early-access form.

Join early access