Self-Hosted Git Server: Gitea vs Forgejo for Your Homelab in 2026
A practical comparison of Gitea and Forgejo for self-hosted Git servers. Learn which lightweight Git platform is right for your homelab, with Docker and Kubernetes deployment guides.
Table of Contents
- The Backstory: Why Two Platforms?
- Quick Comparison
- Feature Breakdown
- Core Capabilities (Both Platforms)
- Where Forgejo Pulls Ahead
- Stability & Testing
- Deployment: Docker Compose
- Gitea Docker Compose
- Forgejo Docker Compose
- First-Time Setup
- Deployment: Kubernetes
- Homelab Integration Tips
- Reverse Proxy Setup
- SSH Access
- Self-Hosted CI/CD with Actions
- Backup Strategy
- Security Hardening
- Which Should You Choose?
- Go with Gitea If:
- Go with Forgejo If:
- Migrating Between Platforms
- Final Thoughts
Running your own Git server gives you complete control over your code, unlimited private repositories, and zero reliance on external platforms. For homelab enthusiasts, the choice usually comes down to two lightweight contenders: Gitea and Forgejo.
Both started from the same codebase, but their paths have diverged significantly. Here’s what you need to know to pick the right one for your setup.
The Backstory: Why Two Platforms?
Gitea launched in 2016 as a community-maintained fork of Gogs, designed to be a lightweight, self-hosted alternative to GitHub. It gained enormous popularity in the self-hosting community.
In late 2022, a group of contributors forked Gitea to create Forgejo. The reason? Growing concerns about Gitea’s governance—specifically, the creation of a for-profit company (Gitea Limited, now CommitGo Inc.) and a perceived shift away from community-driven development.
Forgejo’s mission is clear: radical transparency, democratic governance, and free software principles. They develop using their own platform (dogfooding) instead of GitHub, operate under a non-profit organization (Codeberg e.V.), and focus exclusively on free software.
Quick Comparison
| Feature | Gitea | Forgejo |
|---|---|---|
| Governance | For-profit (CommitGo Inc.) | Non-profit (Codeberg e.V.) |
| Development Platform | GitHub | Forgejo (self-hosted) |
| License Philosophy | MIT + proprietary add-ons | Free software only |
| Testing | Basic testing | Comprehensive E2E + browser tests |
| Security Response | Standard | Faster vulnerability patches |
| Market Presence | More widely adopted | Growing community momentum |
| Cloud/Enterprise | Available | Community-focused |
Feature Breakdown
Core Capabilities (Both Platforms)
Both Gitea and Forgejo offer the same essential features:
- Repository Management — Full Git hosting with branches, tags, and release management
- Issue Tracking — Bug tracking, labels, milestones, and project boards
- Pull Requests — Code review with comments, approvals, and merge options
- Wiki — Built-in documentation for each repository
- Actions — CI/CD pipelines compatible with GitHub Actions syntax
- Package Registry — npm, Maven, PyPI, Docker, and more
- Webhooks & API — Extensive automation capabilities
Where Forgejo Pulls Ahead
Forgejo has developed several features that distinguish it:
- Open Graph Cards — Better social media previews when sharing repositories
- Auto-refreshing Actions Tab — No manual page refresh during CI runs
- Improved Runner Security — Doesn’t automatically mount the Docker socket (major security win)
- LXC Container Builds — More secure isolation than Docker-in-Docker
- 2FA Enforcement — Moderators can require two-factor authentication
- Federation (In Progress) — Future capability for decentralized code hosting
Stability & Testing
This is where Forgejo really shines. Their testing infrastructure includes:
- End-to-end tests
- Upgrade path testing
- Browser tests with accessibility checks
Gitea historically had less comprehensive testing, which could lead to regressions in releases. Forgejo’s rigorous approach means fewer “gotchas” when upgrading.
Deployment: Docker Compose
Both platforms deploy identically via Docker. Here’s a production-ready setup with PostgreSQL:
Gitea Docker Compose
version: "3"
networks:
gitea:
external: false
services:
server:
image: gitea/gitea:1.23
container_name: gitea
environment:
- USER_UID=1000
- USER_GID=1000
- GITEA__database__DB_TYPE=postgres
- GITEA__database__HOST=db:5432
- GITEA__database__NAME=gitea
- GITEA__database__USER=gitea
- GITEA__database__PASSWD=your_secure_password
- GITEA__server__ROOT_URL=https://git.yourdomain.com/
- GITEA__server__SSH_DOMAIN=git.yourdomain.com
restart: always
networks:
- gitea
volumes:
- ./gitea:/data
- /etc/localtime:/etc/localtime:ro
ports:
- "3000:3000"
- "222:22"
depends_on:
- db
db:
image: postgres:16
container_name: gitea_db
environment:
- POSTGRES_USER=gitea
- POSTGRES_PASSWORD=your_secure_password
- POSTGRES_DB=gitea
restart: always
networks:
- gitea
volumes:
- ./postgres:/var/lib/postgresql/data
Forgejo Docker Compose
Nearly identical—just change the image source:
version: "3"
networks:
forgejo:
external: false
services:
server:
image: codeberg.org/forgejo/forgejo:14.0
container_name: forgejo
environment:
- USER_UID=1000
- USER_GID=1000
- FORGEJO__database__DB_TYPE=postgres
- FORGEJO__database__HOST=db:5432
- FORGEJO__database__NAME=forgejo
- FORGEJO__database__USER=forgejo
- FORGEJO__database__PASSWD=your_secure_password
- FORGEJO__server__ROOT_URL=https://git.yourdomain.com/
restart: always
networks:
- forgejo
volumes:
- ./forgejo:/data
- /etc/localtime:/etc/localtime:ro
ports:
- "3000:3000"
- "222:22"
depends_on:
- db
db:
image: postgres:16
container_name: forgejo_db
environment:
- POSTGRES_USER=forgejo
- POSTGRES_PASSWORD=your_secure_password
- POSTGRES_DB=forgejo
restart: always
networks:
- forgejo
volumes:
- ./postgres:/var/lib/postgresql/data
First-Time Setup
After running docker compose up -d, navigate to http://your-server:3000 to complete the installation wizard:
- Verify database connection (should auto-fill from environment variables)
- Set your domain and base URL
- Create an administrator account
- Security tip: Disable self-registration for a private homelab
Deployment: Kubernetes
For Kubernetes homelabs, Gitea maintains official Helm charts:
helm repo add gitea-charts https://dl.gitea.com/charts/
helm repo update
helm install gitea gitea-charts/gitea -n git --create-namespace
A production-ready values.yaml:
replicaCount: 1
image:
repository: gitea/gitea
tag: "1.23"
ingress:
enabled: true
className: nginx
hosts:
- host: git.yourdomain.com
paths:
- path: /
pathType: Prefix
tls:
- secretName: gitea-tls
hosts:
- git.yourdomain.com
persistence:
enabled: true
storageClass: longhorn
size: 50Gi
gitea:
config:
database:
DB_TYPE: postgres
HOST: postgres.git.svc.cluster.local:5432
NAME: gitea
USER: gitea
PASSWD: your_secure_password
server:
ROOT_URL: https://git.yourdomain.com/
For Forgejo on Kubernetes, check for community-maintained Helm charts or adapt the Gitea chart with the Forgejo image.
Homelab Integration Tips
Reverse Proxy Setup
Both platforms work seamlessly behind Traefik, Nginx, or Caddy. For Caddy:
git.yourdomain.com {
reverse_proxy localhost:3000
}
Traefik with Docker labels:
labels:
- "traefik.enable=true"
- "traefik.http.routers.git.rule=Host(`git.yourdomain.com`)"
- "traefik.http.routers.git.tls.certresolver=letsencrypt"
- "traefik.http.services.git.loadbalancer.server.port=3000"
SSH Access
Map port 22 differently (e.g., 222) to avoid conflicts with your server’s SSH. Then configure your ~/.ssh/config:
Host git.yourdomain.com
Port 222
User git
Now you can use standard Git commands:
git clone [email protected]:username/repo.git
Self-Hosted CI/CD with Actions
Both platforms support GitHub Actions-compatible workflows. Deploy a runner:
# docker-compose addition for runner
runner:
image: gitea/act_runner:latest
container_name: gitea_runner
environment:
- GITEA_INSTANCE_URL=http://server:3000
- GITEA_RUNNER_REGISTRATION_TOKEN=your_token
volumes:
- ./runner:/data
- /var/run/docker.sock:/var/run/docker.sock
depends_on:
- server
Get the registration token from your instance: Site Administration → Actions → Runners → Create new Runner token
Backup Strategy
Your data lives in /data inside the container. Key paths:
- Repositories:
/data/git/repositories - LFS files:
/data/git/lfs - Configuration:
/data/gitea/conf/app.ini(or/data/forgejo/conf/app.ini) - Database: Your PostgreSQL volume
For Docker:
# Backup script
docker exec gitea gitea dump -c /data/gitea/conf/app.ini
# Or for Forgejo:
docker exec forgejo forgejo dump -c /data/forgejo/conf/app.ini
This creates a timestamped backup with all repositories, database, and configuration.
Security Hardening
- Disable self-registration if it’s a private instance
- Enable 2FA for all accounts
- Use strong passwords for database and admin
- Restrict SSH keys to only needed users
- Firewall rules that only allow trusted networks for homelab access
Which Should You Choose?
Go with Gitea If:
- You want stability and proven adoption — It’s been around longer with more documented setups
- Enterprise or cloud options matter — Gitea offers hosted and enterprise tiers
- You integrate with many external tools — Larger ecosystem of plugins and guides
- You don’t care about governance nuances — Just want the job done
Go with Forgejo If:
- You value open-source principles — Non-profit, community-driven, no corporate agenda
- Privacy and security are priorities — Faster security patches, privacy-focused development
- You want better testing — Fewer surprises during upgrades
- You support free software — Everything is free/libre, no proprietary add-ons
For most homelabbers, Forgejo is the better choice in 2026—unless you have specific enterprise needs or rely on Gitea-specific integrations. The governance difference may seem philosophical, but it translates to real benefits: transparent decision-making, faster security fixes, and a community-first approach.
Migrating Between Platforms
Going from Gitea to Forgejo (or vice versa) is straightforward since they share a common origin:
- Backup Gitea:
gitea dumpto create a backup archive - Stop the instance:
docker compose down - Restore to Forgejo: Point Forgejo at the Gitea data directory
- First run: Forgejo will migrate the database schema
The reverse works similarly. Always backup before migrating.
Final Thoughts
Both Gitea and Forgejo are excellent self-hosted Git platforms—they’re lightweight, feature-complete, and perfect for homelab use. The real question isn’t “which is better” but “what matters to you?”
If you just want a Git server that works, either will serve you well. If you care about where your software comes from and how it’s governed, Forgejo aligns better with open-source values.
Either way, you’re taking control of your code. That’s what homelabbing is all about.
Have questions about setting up Gitea or Forgejo? Drop by the comments or hit me up on the homelab Discords.

Comments
Powered by GitHub Discussions