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
| Option | Who runs the hardware | Access | Good for |
|---|---|---|---|
| Hosted Forgejo Actions | Codeberg | Public, free-licensed repos; enable Actions | Linters, short test suites |
| Woodpecker at ci.codeberg.org | Codeberg | Request form, manual approval | Longer builds on amd64 |
| Your Forgejo Runner | You | Any repo you administer | Heavy builds, arm64, GPUs, private repos |
| Your Woodpecker agent | You | Approved ci.codeberg.org users | Extra 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-smalllabel. 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-onchanges. - 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:
| Label | Arch | CPU | RAM | Max runtime |
|---|---|---|---|---|
codeberg-tiny | amd64 | 1 | 2 GB | 2 min |
codeberg-small | amd64 | 2 | 4 GB | 5 min |
codeberg-medium | amd64 | 4 | 8 GB | 10 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:
- Read the criteria your project must meet.
- Submit the Woodpecker access request.
- Once a volunteer approves it, log in to ci.codeberg.org with your Codeberg account.
- 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
- Enable Actions in the repository (Settings, Units, Overview). Codeberg ships it disabled.
- Open Settings, Actions, Runners in the repository, organization or user settings.
- 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.
- 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. - 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
dockerlabels and never onhostlabels. - Register the runner at repository scope unless you need it across an org.
- Store the token outside the config with
token_urland systemd credentials, and keepcontainer.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