Gitea: your own GitHub, minus the cloud
Every good homelab eventually hits the same wall: you have scripts, Ansible playbooks, Terraform configs, and Docker Compose files scattered across your workstation, maybe backed up somewhere, maybe not. You’re either committing to GitHub (which means your private infrastructure code lives on someone else’s server) or you’re living dangerously with no version control at all. Neither feels right.
That’s the moment a self-hosted Git service stops being a “nice to have” and becomes obvious.
What is Gitea, in plain language?
Gitea is a web application that gives you a GitHub-style experience — repository browser, commit history, pull requests, issue tracker, webhooks, user accounts, organizations — but runs entirely on your own hardware. You own the data. You control who can see what. No monthly seat count, no storage limits billed by the gigabyte, no terms-of-service update that quietly broadens what the platform can do with your code.
If you’ve used GitHub or GitLab, the interface is immediately familiar. There’s a web UI for browsing and reviewing code, SSH and HTTPS clone URLs, branch protection rules, and a webhook system for triggering automation on push or merge events. It’s not a stripped-down toy — it’s a legitimate developer tool that happens to be small enough to run on modest hardware.
The problem it solves
Version control is table stakes for any infrastructure work. But there’s a meaningful difference between using Git and self-hosting a Git service, and it’s worth being explicit about why the latter matters in a homelab context.
Your infrastructure code is sensitive. Terraform state, Ansible inventory, Docker Compose files with service configurations, scripts that touch production systems — none of this belongs on a public or semi-public platform by default. Even private GitHub repos are ultimately stored on infrastructure you don’t control, subject to Microsoft’s policies, and accessible to GitHub support staff. That may be a perfectly acceptable tradeoff for many people. It just isn’t the self-hosting philosophy.
You want a single source of truth inside the network. When you’re running CI/CD, triggering automation from webhooks, or just cloning a repo on a new VM, you want the authoritative copy to live at a known, stable internal address — not dependent on external connectivity, not subject to rate limits, not creating a hairpin through the public internet for a clone operation that never needed to leave your rack.
Change history matters. Infrastructure that isn’t tracked in version control is infrastructure that eventually fails in mysterious ways. Self-hosting Git removes every remaining excuse not to commit your configs.
The commercial equivalent
The obvious comparison is GitHub. It’s the dominant platform, has excellent tooling, and the free tier is generous. For open-source or public work, it’s often the right answer. For private homelab infrastructure, you’re paying (in trust and dependency) for convenience you don’t necessarily need.
GitLab’s SaaS product is the other major player, particularly popular for teams that want a fully integrated DevOps platform — CI/CD pipelines, container registry, security scanning, project management — all in one place. It’s powerful, but it’s also expensive at scale and architecturally heavy.
Neither is wrong. They’re just optimized for different things than a homelab.
The self-hosted options worth knowing
If you’ve decided to self-host your Git service, three options come up consistently:
GitLab Community Edition is the open-source version of the SaaS product. It is genuinely feature-complete: built-in CI/CD runners, container registry, pages, security scanning, merge request workflows, LDAP/SAML/OIDC integration. If you need an all-in-one DevOps platform and have the resources to run it, it delivers. The catch is resource appetite — GitLab CE wants multiple gigabytes of RAM at idle and a meaningful amount of CPU. It’s not a service you tuck into a corner of a small VM.
⚠️ Unverified: GitLab CE RAM requirements vary by version and configuration; the “multiple gigabytes at idle” characterization reflects general community experience rather than a specific benchmark.
Forgejo is a community-driven fork of Gitea that emerged after Gitea’s governance shifted toward a for-profit model in 2022. It’s functionally nearly identical to Gitea — same codebase lineage, same lightweight profile, same API surface — but maintained by a different group with a more explicitly open governance structure. If you start a new deployment today, Forgejo is worth evaluating alongside Gitea; the two are close enough that most tutorials and documentation apply to both.
⚠️ Unverified: The specific governance history and fork timeline are general community knowledge; verify current status at forgejo.org before making a decision.
Gitea is where many homelabbers land: small resource footprint, fast, easy to deploy via Docker, and rich enough in features that it handles real infrastructure workflows without friction. It’s what this lab runs, and it’s proven itself as a foundation service — the kind of service that other things depend on rather than the other way around.
How it fits a homelab in practice
In this lab, Gitea runs as a Docker Compose stack — a Gitea container paired with a PostgreSQL database — on a small VM. Two CPU cores and a few gigabytes of RAM is all it needs. It runs behind a reverse proxy for HTTPS, uses SSH for Git operations, and sits behind SSO for web access. The whole thing is straightforward to deploy, update, and back up.
The repos it hosts aren’t just infrastructure code. There’s a separation between the IaC repository (Terraform, Ansible, the actual machine configs) and a documentation repository (Obsidian-synced KB, runbooks, decisions). Keeping them separate means tighter access control — the IaC repo is more sensitive than the docs.
A few things that make this setup feel production-grade rather than hobbyist:
Organizations and teams. Gitea has a GitHub-style organization model, so you can group repos logically and manage access at the team level rather than granting per-user permissions on every repository individually.
Webhooks as the automation backbone. Every meaningful event — a push to main, a merged pull request, a new tag — can fire a webhook to downstream automation. In this lab that means notification services and workflow automation pick up Git events without polling. The webhook system is the glue between code changes and the rest of the homelab.
Mirroring outward. Gitea supports repository mirroring, so public or backup copies can exist on GitHub without GitHub being the source of truth. The canonical copy lives on your hardware; the mirror is just belt-and-suspenders redundancy. This is particularly useful for anything you want to share publicly while still controlling the authoritative version locally.
Actions compatibility. Gitea supports a GitHub Actions-compatible workflow syntax, meaning CI/CD pipelines you’ve written for GitHub can run on self-hosted runners against your Gitea instance. That’s a meaningful upgrade path if you want automated testing or deployment pipelines without adding a separate CI system.
The honest resource cost
Gitea is light. This is one of its strongest selling points. A properly sized deployment doesn’t need much — a couple of virtual CPU cores and a few gigabytes of RAM handles a homelab workload comfortably. That’s in the noise of what a reasonably provisioned homelab VM uses for essentially any other service.
PostgreSQL adds a dependency but also adds reliability. SQLite is supported for simpler setups, but for anything you intend to treat as a critical service, running a proper database backend is worth the small added complexity. The database also makes Gitea easier to back up in a structured way, since you can rely on standard PostgreSQL tooling rather than filesystem snapshots that depend on timing.
Backup is straightforward: Gitea has a built-in dump command that archives everything — repositories, database, configuration, attachments, SSH keys — into a single zip file. You can also back up the PostgreSQL database directly with pg_dump if you want finer-grained control. Either approach integrates cleanly with whatever backup strategy you’re already running. In this lab, Gitea backups run on a daily schedule alongside other critical services, with offsite copies going to cloud storage. The goal is that a complete rebuild from scratch should be a restore operation, not a reconstruction from memory.
Updating Gitea is also low-drama: pull a new container image, recreate the container, done. Because state lives in named Docker volumes and the PostgreSQL database, updating the application doesn’t touch your data. This is exactly the kind of operational property that makes a service easy to maintain over years rather than becoming a thing you’re afraid to touch.
Who should run this
If you have infrastructure as code — and you should — you need a place to put it. If you care about keeping that code private and on hardware you control, a self-hosted Git service is the natural answer. Gitea hits the sweet spot of low resource cost, adequate features, and fast setup time.
You don’t need a large homelab to justify it. If you have even one Ansible playbook or one Docker Compose file you’d be annoyed to lose, that’s enough reason to version-control it properly — and once you’re doing that, self-hosting the service is a small additional step.
Who should skip it
If your code is already on GitHub, you’re happy with GitHub, and the trust tradeoffs don’t concern you, there’s no compelling reason to change. Self-hosting adds operational surface area: you become responsible for uptime, updates, and backups. For someone who just wants their dotfiles tracked somewhere reliable, that overhead isn’t worth it. GitHub’s free tier is genuinely good and the platform is highly unlikely to disappear. The case for self-hosting is about ownership and control, not about GitHub being bad.
Similarly, if you want a complete DevOps platform with built-in CI, container registry, and security scanning integrated from the start, GitLab CE is the stronger choice — provided you have the hardware to feed it. Gitea with Actions bolted on is capable, but it’s not the same integrated experience as GitLab’s native pipeline system. If your team (even a team of one, with ambitious automation goals) wants CI/CD to feel first-class from day one and you can spare the RAM, GitLab CE is worth the heavier footprint.
The last case to honestly flag: if you’re new to self-hosting and still figuring out your backup discipline, a Git service is an interesting choice for an early deployment because the data inside it is often the thing that lets you rebuild everything else. That’s a reason to take its backup seriously before you start relying on it, not a reason to skip it. But know that going in.
Closing thought
Version control is one of those disciplines that starts feeling optional until the moment it very obviously isn’t. The homelab equivalent of “I’ll back that up later” is “I’ll add that to Git eventually” — and eventually tends to arrive right after something breaks in a way you can’t easily reconstruct.
Running Gitea removes the last friction point. Your infrastructure code lives at a known address, on hardware you own, versioned, accessible to automation, and backed up as part of your regular backup strategy. It’s a small service that makes everything else more trustworthy.
That’s a good return on a couple of gigabytes of RAM.
Comments
No comments yet — be the first.