Running GitHub‑Actions‑Style CI on Your Own Forgejo Server
Forgejo’s native support for external runners lets you run CI/CD pipelines on your own hardware. This guide walks through configuring a self‑hosted runner, adding a simple workflow, and highlights trade‑offs such as resource use and token security.
25 Jun 2026, 00:58 UTC

Problem: On‑Prem CI/CD for Strict Compliance
Many organizations host their Git repositories on a private Forgejo instance to keep code within corporate firewalls. However, running continuous integration (CI) pipelines becomes a challenge: you either use a third‑party hosted service (which violates data‑privacy rules) or build your own pipeline system from scratch. Both options add operational overhead and cost.
Forgejo 1.14+ solves this by offering native integration with external CI runners that understand the GitHub Actions workflow format. You can spin up a dedicated runner on your own servers, register it with Forgejo, and run pipelines locally without external dependencies.
Forgejo’s Built‑in Runner Support
Forgejo treats external runners as first‑class citizens. After registering a runner, any workflow file placed under .github/workflows/ will be discovered automatically. The runner authenticates with a short‑lived token and reports status back to the Forgejo UI, just like GitHub Actions.
Configuring a Self‑Hosted Runner
- Navigate to the Runner Settings
Open the repository or organization settings, then click Actions → Runners. You must have administrative privileges on the target repository or org. - Register a New Runner
Click Add runner, give it a name (e.g.,ci-runner-01), and copy the registration token shown. This token is only valid for the next 10 minutes by default. - Run the Registration Script
On the machine that will host the runner, open a terminal and execute:
Replacecurl -fsSL https://forgejo.example.com/_actions/runner/registration_script.sh | bashforgejo.example.comwith your Forgejo domain. The script will:- Download the runner binary appropriate for your OS.
- Place it in
$HOME/.forgejo-runner(you can choose a different directory). - Create a service file so the runner starts automatically.
- Use the token you copied earlier to authenticate.
- Start the Runner
If the script installed a systemd service, enable and start it:
If you prefer a manual approach, runsudo systemctl enable --now forgejo-runner./run.shfrom the runner directory. - Verify Registration
Back in the Forgejo UI, the new runner should appear with status Online. The runner will now accept jobs from any workflow that matches its label.
Security note: Store the registration token in a secure location (e.g., ~/.forgejo-runner/token with 0600 permissions). Exposing this token allows anyone to run arbitrary code on the host machine.
Adding a Simple Workflow
Create a new repository or use an existing one. Add a file at .github/workflows/ci.yml with the following content:
name: CI
on:
push:
branches: [ main ]
jobs:
test:
runs-on: self-hosted
steps:
- name: Checkout
uses: actions/checkout@v4
- name: Echo a Message
run: echo "Hello from the self‑hosted runner!"
- name: Run Test Script
run: ./run_tests.sh
The key line is runs-on: self-hosted. This tells Forgejo to dispatch the job to any registered self‑hosted runner. The workflow checks out the repository and runs a local script named run_tests.sh (you can replace it with your unit tests).
Running and Verifying the Job
- Commit and push the workflow file to the
mainbranch.git add .github/workflows/ci.yml git commit -m "Add CI workflow" git push origin main - In the Forgejo UI, navigate to Actions. You should see a new run titled CI.
- Click the run to view logs. The output should include your echo message and the result of
run_tests.sh. - Check that the runner service is still running and that no excessive CPU or memory usage spikes occurred.
Verification tip: If the job fails to appear, confirm the runner’s service status and that the token was correctly configured. Look for log entries in /var/log/forgejo-runner.log (or the runner’s own log path).
Trade‑offs & Limitations
- Resource Contention: Running CI jobs on the same machine that hosts Forgejo can saturate CPU and I/O. Consider dedicated runner hosts or containerized runners (Docker, Podman) to isolate workloads.
- Token Management: The registration token is short‑lived. If you need to re‑register a runner (e.g., after a reboot), you must generate a new token and run the registration script again.
- Security Exposure: Any process running on the host can access the runner token if it is stored insecurely. Use encrypted storage or environment variables with restricted permissions.
- Feature Parity: While the runner supports GitHub Actions syntax, some advanced GitHub Actions features (e.g., cache, secrets management) may require additional configuration on Forgejo.
Next Steps
1. Scale Out: Add multiple runners with different labels (e.g., docker, linux-x64) to parallelize jobs.
2. Automate Runner Provisioning: Use Terraform or Ansible to spin up new runner instances and automatically register them with Forgejo.
3. Secure Secrets: Store build secrets in Forgejo’s Settings → Secrets and reference them in your workflow with ${{ secrets.MY_SECRET }}.
4. Monitor Performance: Integrate metrics (Prometheus, Grafana) to track runner utilization and detect bottlenecks.
5. Backup Runner Configuration: Keep a copy of the runner’s config.toml and token in a secure vault; this aids quick recovery after hardware failure.
By following these steps, you can bring the power of GitHub Actions‑style CI to your private Forgejo environment, keeping code and pipelines within your own infrastructure while enjoying a familiar workflow format.
0 replies
A thoughtful contribution can make all the difference. Be the first to share one.