Gitea
Git Hosting & ForgesLightweight self-hosted Git service
Replaces GitHub, GitLab
Git hosting, issues, pull requests
Your code, your runners, your release pipeline.
Gitea provides repositories, issues, and pull requests in a single lightweight binary, and Woodpecker CI — itself a community fork born from self-hosting needs — runs container-based pipelines triggered by Gitea webhooks. The pair covers the GitHub-plus-Actions workflow for a fraction of the resources GitLab needs, which is exactly the trade most homelabs and small teams want.
Last reviewed Oct 11, 2026 · 661 words
Gitea plus Woodpecker CI gives you repositories, pull requests and container-based pipelines in about 512 MB of RAM by the directory's estimates, 256 MB for each. The wiring is two things: Woodpecker logs in through a Gitea OAuth application, and Gitea sends Woodpecker a webhook on every push. Get the URLs right on both sides and run the build agent somewhere other than the Gitea host, and the pair needs little attention afterwards.
Gitea is the source of truth for code, users and permissions. Woodpecker does not manage passwords: you create an OAuth2 application in Gitea, give Woodpecker the client ID and secret, and users sign in to Woodpecker with their Gitea accounts. When someone activates a repository in Woodpecker, it registers a webhook on that repository in Gitea.
Woodpecker itself is two parts. The server receives webhooks, shows the UI and schedules work. One or more agents connect to the server and run each pipeline step in its own container, using the YAML file in the repository. Agents need access to a container runtime, and that is where most of the security thinking in this stack goes.
| Component | Talks to | Rated | Directory RAM estimate |
|---|---|---|---|
| Gitea | Woodpecker server (webhooks) | Easy | 256 MB |
| Woodpecker server | Gitea (OAuth, API), agents | Medium | 256 MB |
| Woodpecker agent | Woodpecker server, Docker | Medium | Grows with builds |
The agent's real footprint is whatever your builds need; a compiler or test suite will use far more than the server ever does.
Gitea first, behind your reverse proxy with its final public URL set as ROOT_URL before anyone clones anything. Every link Gitea generates, including OAuth redirects and webhook payloads, is built from it. Map container SSH to a spare host port, as the catalogue does with 222, and expect that port to appear in clone URLs.
Then create the OAuth application in Gitea with Woodpecker's callback URL, deploy the Woodpecker server with those credentials, and deploy one agent with the shared secret that lets it register. Activate one test repository and push a trivial pipeline before migrating anything real.
Usually because Gitea refuses to deliver the webhook. Gitea restricts webhook targets by default and blocks deliveries to private network addresses, which is exactly where a homelab Woodpecker server lives. The push succeeds, Woodpecker sits idle, and the only clue is a failed delivery in the repository's webhook settings. Add your Woodpecker host to Gitea's webhook allowed-host list, or route the webhook through the public hostname, and builds start arriving. Check the delivery log before you debug anything else.
A Woodpecker agent with the Docker socket mounted has root-equivalent control over its host, and it runs code from any repository you activate, including pull requests. Put that on the same machine as Gitea and a malicious or simply careless pipeline can read every repository on disk. Run agents on a separate VM or machine, and do not enable builds for pull requests from forks you do not trust.
Also decide early between Woodpecker and Gitea's built-in Gitea Actions. Running both on the same repositories means two sets of pipeline files and two places to look when something fails.
Gitea's /data volume holds repositories, the database (if you kept SQLite), attachments and configuration; back it up as a unit. Woodpecker's server database holds build history and secrets. Agents are stateless and can be rebuilt.
Deploy Gitea with the correct ROOT_URL, add Woodpecker with one agent on a separate VM, and fix the webhook allow-list before your first push. If you are still choosing a forge, the self-hosted Git forges guide and the Forgejo vs Gitea comparison cover the fork, and Woodpecker works with Forgejo the same way.