Sometimes the code cannot live on GitHub. A closed network, a client contract, a regulator, or simply not wanting a company between you and your history — and the alternative used to be GitLab, which is a real deployment with real hardware behind it.

Gitea is the small answer: one Go binary, an embedded database if you want one, and repositories, pull requests, issues, wikis, releases, a package registry, and CI in the interface everyone already knows. It runs comfortably on a machine you’d otherwise call too small.

Run one

  docker run -d --name gitea -p 3000:3000 -p 222:22 \
  -v gitea-data:/data \
  -e GITEA__database__DB_TYPE=sqlite3 \
  docker.io/gitea/gitea:latest
  

Open http://localhost:3000, complete the install screen, and the first account you create is the administrator. SQLite is genuinely fine for a small team; move to Postgres when you have concurrency or a backup story that wants it.

Everything you’d otherwise click lives in /data/gitea/conf/app.ini — and every setting in it has a GITEA__section__KEY environment variable, which is what makes it pleasant in Docker Compose or Kubernetes.

What you get

FeatureNotes
Repositories, PRs, issues, reviewsThe GitHub model, including protected branches and required approvals
Gitea ActionsGitHub Actions-compatible workflows; most marketplace actions run unchanged
Package registrynpm, PyPI, Maven, Docker, Helm and more, built in
MirroringPull from or push to GitHub, so it can be a warm backup rather than a migration
Webhooks and APIAn API close enough to GitHub’s that scripts port easily
SSOLDAP, OAuth2, SAML in recent versions

Mirroring is the underrated one: point Gitea at your GitHub repositories and it keeps a synchronised copy. That’s an evening of work and a genuine answer to “what if we lose access to our account.”

CI, without a second system

  docker run -d --name act-runner \
  -v /var/run/docker.sock:/var/run/docker.sock \
  -e GITEA_INSTANCE_URL=http://gitea:3000 \
  -e GITEA_RUNNER_REGISTRATION_TOKEN=<token> \
  gitea/act_runner:latest
  
  # .gitea/workflows/ci.yml
name: CI
on: [push, pull_request]
jobs:
  test:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
      - run: npm ci && npm test
  

If that looks exactly like GitHub Actions, that’s the point — the workflow syntax is the same and the common actions work. Two caveats worth knowing before you plan a migration: actions are fetched from GitHub by default (mirror them locally for an air-gapped install), and the more exotic GitHub-hosted features have no equivalent.

Gitea or Forgejo?

Forgejo forked from Gitea in 2022 over governance — Gitea’s move to a company structure — and the two have since diverged enough that they’re no longer drop-in interchangeable.

GiteaForgejo
LicenceMIT, with a commercial editionGPL from v9 onward
GovernanceGitea Ltd plus communityCodeberg e.V., community-owned
CIGitea ActionsForgejo Actions — same idea
Distinctive workEnterprise featuresActivityPub federation between forges

For most self-hosters either is a good answer and the day-to-day experience is nearly identical. Choose Forgejo if community governance and a copyleft licence matter to you; Gitea if you want the MIT licence or a commercial support option.

Worth knowing which way the door swings: Gitea → Forgejo is documented and supported, often little more than swapping the image. The reverse is not a supported path, and since the 2024 hard fork the two are no longer drop-in interchangeable. Forgejo has its own page if that’s the direction you’re leaning.

Running it in earnest

  • Back up /data and the database together. A repository backup without the issues and pull requests loses the discussion, which is often the more valuable half.
  • Put TLS in front of it — a reverse proxy with cert-manager or Caddy, and set ROOT_URL correctly or clone URLs come out wrong.
  • Keep SSH on its own port and decide early between the built-in SSH server and the host’s; mixing them is a common source of confusion.
  • Watch the upgrade notes. Migrations run on start, so take the backup first.

Next

The other side of the fork, and the case for it → Forgejo

Last updated 25 Aug 2026, 00:00 UTC. history