Self-hosting Git ranges from bare repos over SSH (15 minutes setup) to Gitea (a small team’s GitHub clone) to GitLab (full enterprise platform with CI/CD). The team that picks bare repos gets the simplest setup with no web UI; the team that picks Gitea gets a GitHub-like web UI without GitLab’s resource cost; the team that picks GitLab gets the full platform with the full operational overhead. The right pick depends on team size, need for issue tracking and CI/CD, and how much operational complexity the team is willing to absorb.
Table of contents
- The simplest path: bare repos over SSH
- Gitea: GitHub-like without GitLab’s overhead
- GitLab: full enterprise platform
- Other options
- Operational considerations
- FAQ
The simplest path: bare repos over SSH
Create a bare repo on the server: git init --bare /srv/git/myrepo.git. Add a remote on the client: git remote add origin user@server:/srv/git/myrepo.git. The team that has a server with SSH access has a Git server in 5 minutes.
Authentication: SSH keys. The team that has SSH key authentication set up (most servers do) gets Git access for free. The team that needs password authentication sets up a git user with a password, but SSH keys are the modern default.
No web UI. The team that uses bare repos over SSH has no issue tracking, no pull request workflow, no code review UI. The team that needs these adds Gitea, GitLab, or a hosted solution (GitHub, GitLab.com, Bitbucket).
No access control granularity. The team that uses bare repos has Unix-level permissions - any SSH user with read access to the repo directory can read it. The team that needs per-branch or per-team access picks a platform with built-in access control.
Gitea: GitHub-like without GitLab’s overhead
Gitea is a lightweight self-hosted Git service written in Go. Single binary, MySQL/SQLite/Postgres backend, web UI similar to GitHub. The team that runs Gitea gets issues, pull requests, code review, releases, wiki, and a package registry - all in a 256MB RAM footprint.
Setup: apt install gitea or run the Docker image. The Docker image is the simplest - docker run -d --name gitea -p 3000:3000 -p 22:22 gitea/gitea:latest. The team that has Docker has Gitea running in 5 minutes.
Migration from GitHub or GitLab: import repositories. Gitea has built-in migration tools - paste the GitHub repo URL, Gitea clones it, preserves issues and pull requests. The team that migrates from GitHub.com to self-hosted Gitea keeps history.
The team that uses Gitea has: web UI, issue tracking, PR workflow, code review, releases. Does not have: full CI/CD (use Gitea Actions or external CI), Kubernetes integration, advanced security scanning. The team that needs these adds Gitea Actions or picks GitLab.
GitLab: full enterprise platform
GitLab is the full-featured self-hosted Git platform with built-in CI/CD, security scanning, container registry, and Kubernetes integration. The team that runs GitLab gets the entire DevOps platform in one application.
Resource cost: 4GB RAM minimum for a small instance, 8GB+ recommended. GitLab is heavy because it bundles many services (Postgres, Redis, Sidekiq, Puma, Gitaly, container registry, etc.). The team that runs GitLab on a 1GB VPS has performance issues; the team that runs on 4GB+ has a workable instance.
Setup: Omnibus package or Docker image. The Omnibus package (apt install gitlab-ee) bundles everything and manages upgrades. The Docker image (gitlab/gitlab-ee:latest) is easier to manage but requires more disk and memory.
The team that uses GitLab has: web UI, issues, merge requests, CI/CD, security scanning, container registry, Kubernetes integration, monitoring. The team that does not need all of these picks Gitea or bare repos and avoids the operational complexity.
Other options
Forgejo: community fork of Gitea. Maintained by the community after Gitea moved to a more commercial model. The team that wants fully open-source governance picks Forgejo. Feature parity with Gitea for most use cases.
SourceHut: email-driven, minimal UI. For teams that prefer email-based workflows. The team that wants a different paradigm (no web-based code review) picks SourceHut. Smaller community than Gitea/GitLab.
Phabricator: discontinued but still used. The team that has an existing Phabricator instance keeps it; the team starting fresh picks something else. Phabricator development stopped in 2021.
OneDev: all-in-one DevOps platform. Git, issues, CI/CD, kanban, code search. The team that wants a single self-hosted tool for everything picks OneDev. Smaller community than GitLab.
Operational considerations
Backups. Git repositories are directories; back up the data directory. The team that uses bare repos backs up /srv/git/. The team that uses Gitea backs up the Gitea data directory AND the database. The team that uses GitLab backs up the entire /etc/gitlab, /var/log/gitlab, /var/opt/gitlab directories.
Updates. Gitea updates are simple - replace the binary and restart. GitLab updates are more involved - Omnibus package handles it, but major version upgrades (14 to 15 to 16) need attention. The team that runs GitLab has a quarterly upgrade cadence.
SSO and authentication. All three support LDAP, OIDC, SAML. The team that uses corporate SSO picks the platform that integrates with their IdP. Gitea and GitLab both have free tiers for SSO; some features require paid tiers.
Run a reverse proxy (nginx, Caddy, Traefik) in front. Git over HTTPS, web UI on port 443, SSH on port 22 (or alternate port via SSH config). The team that runs Gitea behind nginx has clean HTTPS termination and SSH access through the same host.
FAQ
What is the easiest self-hosted Git?
Bare repos over SSH. The team that has a server with SSH access sets up Git in 5 minutes: git init --bare, add a remote, push. The team that needs a web UI picks Gitea (single binary, Docker image) for the next step up.
Should I use Gitea or GitLab?
Gitea for small teams (1-20 developers) that want a GitHub-like UI without GitLab’s resource cost. GitLab for larger teams (50+) that need full CI/CD, security scanning, and Kubernetes integration. The team that picks Gitea gets faster setup and lower resource use; the team that picks GitLab gets a full platform with operational overhead.
Can I migrate from GitHub to self-hosted Git?
Yes. Gitea has built-in GitHub migration (preserves issues, PRs, releases). GitLab has GitHub import. The team that uses these tools keeps history. The team that needs bulk migration uses ghe-migrator (GitHub Enterprise) or git commands for repos only.
What port does Git use for SSH?
22 by default. The team that runs Gitea or GitLab on a host that already has SSH can map Git SSH to a different port (e.g., 2222) via the Gitea config or gitlab.rb. The team that uses the default port 22 needs SSH configured for the host’s other services.
How do I add access control to a bare repo?
Use Unix permissions and groups. The team that wants a ‘devs’ group with read-write access and ‘viewers’ group with read-only access sets up Linux groups and chmod on the repo directory. For more complex access control (per-branch, per-team), use Gitea or GitLab.
Can I self-host Git for free?
Yes. Bare repos over SSH are free (no software beyond git itself). Gitea is MIT-licensed and free. GitLab Community Edition is MIT-licensed and free. The team that runs any of these has no per-user or per-repo licensing cost; the cost is the server that hosts them.
How this fits the rest of the stack
For a sense of what the full project costs before it commits, the RunxBuild hosting calculator shows the line items together. The API, the database, the storage, the worker, the bandwidth - each one is a separate number, and the team’s mental model for the platform is the sum of those numbers.
Useful related references: