In my previous article, First steps towards Codeberg, we looked at how to get set up and comfortable on the platform. Now that your code has a new home, it’s time to level up your workflow with automation.
While Codeberg provides shared runners for CI/CD, there are plenty of reasons to run your own, among others,
- performance
- specific hardware requirements
- avoiding queue times
In this guide , I'll show you how to use your local machine as a CI/CD runner for Codeberg. This works behind firewalls and home routers without needing to expose your IP address. Sounds cool, right?
Depending on your needs, you can choose between two setup methods: the containerized approach using Docker / OrbStack, or running the act_runner binary directly. Since I am on a Mac with Apple Silicon, the choice actually matters quite a bit. Docker on M-series chips runs Linux ARM64 images, and unfortunately, the standard Android build tools don't officially support that environment yet. If you are here for Android builds, you might want to look at the binary method; otherwise, Docker is a safe bet.
First, get your registration token.
- On Codeberg, navigate to Settings > Actions > Runners
- Click Create new runner
- Copy the Registration Token
Next, prepare the workspace.
Docker / OrbStack
Open your terminal and create a folder to house the runner's identity and configuration.
mkdir codeberg-runner
cd codeberg-runner
After that, create the configuration by putting a file named docker-compose.yml in that folder:
code docker-compose.yml
Here's how that file should look like. Replace <TOKEN> and <name-of-your-runner> with your registration token and a name for your runner. <name-of-your-runner> will appear in the Codeberg dashboard.
services:
runner:
image: gitea/act_runner:latest
container_name: codeberg_runner
restart: always
environment:
- GITEA_INSTANCE_URL=https://codeberg.org
- GITEA_RUNNER_REGISTRATION_TOKEN=<TOKEN>
- GITEA_RUNNER_NAME=<name-of-your-runner>
- ACT_RUNNER_DEFAULT_IMAGE=gitea/runner-images:ubuntu-22.04
volumes:
- /var/run/docker.sock:/var/run/docker.sock
- ./data:/data
command: daemon
Now we can launch and register our runner. Run the following command from inside the codeberg-runner folder. This will pull the image, register the runner automatically, and start the background service.
docker compose up -d
To verify the connection you can check the logs to ensure the registration was successful.
docker logs codeberg_runner
You should see Starting runner daemon.
You'll also see your runner in the Codeberg settings.
Once the initial setup is complete, use these commands to control your runner:
| Action | Command | Result |
|---|---|---|
| Go Offline | docker compose stop |
Safely pauses the runner; it will show as "Offline" on Codeberg |
| Go Online | docker compose start |
Reconnects to Codeberg; the runner will show as "Idle" (ready) |
| View Live Logs | docker compose logs -f |
Streams the activity; you'll see jobs being picked up in real-time. |
| Check Identity | ls -la ./data |
Verifies the .runner file exists (your runner's "ID card") |
That's it. Your Docker-based runner is now active and polling for jobs. To use it, you simply need to update your workflow file (usually in .gitea/workflows/) to target this specific runner.
jobs:
test:
runs-on: blackmac-runner
steps:
- run: echo "Hello from my local runner!"
In the next section, I'll show you an alternative method. act_runner is the lightweight binary that powers the Docker image we just used. By configuring it with a host label, we can run jobs directly on your machine without a container layer. This allows the runner to access your local tools (for example, Xcode or the Android SDK) directly. As mentioned earlier, this is the preferred method if you need to break out of the container's isolation or are dealing with architecture-specific limitations on Apple Silicon.
act_runner
First, let's install act_runner. We will also install node, which is required to run standard actions (like actions/checkout) directly on the host machine.
brew install act_runner node
Next, generate the default configuration file so we can customize the runner settings.
mkdir -p ~/.config/act_runner
act_runner generate-config > ~/.config/act_runner/config.yaml
Open ~/.config/act_runner/config.yaml and locate the runner section. Add your custom label ending in :host to ensure jobs run directly on your machine:
runner:
labels:
- "blackmac-runner:host"
Now we can register the runner. Replace YOUR_REGISTRATION_TOKEN with the one you obtained from the Codeberg settings earlier. This command links your local machine to the instance using the configuration and label we just defined.
act_runner register --no-interactive \
--instance https://codeberg.org \
--token YOUR_REGISTRATION_TOKEN \
--name blackmac-runner \
--labels blackmac-runner:host \
--config ~/.config/act_runner/config.yaml
Finally, start the runner daemon. It will connect to Codeberg and immediately begin listening for incoming jobs.
act_runner daemon --config ~/.config/act_runner/config.yaml
And we are live! The daemon is now connected to Codeberg and listening for jobs. To use it, simply reference the label we just registered (blackmac-runner) in your workflow file, exactly as shown earlier. The key difference here is that your jobs will now execute directly on your Mac's host system, bypassing the container layer and giving you full access to local tools like Xcode or the Android SDK.



Top comments (0)