Self-Hosting a Git Server on Raspberry Pi with Gitea
If you write firmware, Klipper macros, KiCad projects, or scripts for your maker setup, a private Git server on a Raspberry Pi gives you version control and remote-pushable backups without putting project files on GitHub or GitLab's cloud. Gitea is a lightweight, self-contained Git server with a GitHub-like web UI, issue tracking, and pull requests, and it runs comfortably on a Raspberry Pi 4 or 5 with room to spare. This guide covers installing it via Docker, first-run setup, and getting your first repository pushed.
Why Self-Host Git Instead of Using GitHub
Self-hosting makes sense when you want project history and backups to live entirely on hardware you control (useful for anything you don't want on a third-party cloud, from personal projects to client work under an NDA), when you want unlimited private repositories without a paid plan, or when you're already running a Raspberry Pi homelab and want one more self-hosted service instead of another cloud account. It's a different use case from this site's guide to running a Gitea Actions CI/CD runner on a Pi — that article covers using Gitea (or GitHub) Actions as an automated build/test runner; this one is about Gitea as your actual Git remote, the place your repositories live and that you `git push` to day to day.
Installing Gitea with Docker Compose
Docker is the simplest path to a maintainable Gitea install on a Pi, since it isolates Gitea's dependencies and makes upgrades a matter of pulling a new image tag rather than managing a system-level Go installation. Install Docker and Docker Compose on Raspberry Pi OS (64-bit is recommended for Docker workloads), create a working directory, and write a docker-compose.yml defining the Gitea service along with a Postgres or MySQL container if you want a database beyond Gitea's default SQLite (SQLite is fine for a single-user or small-team homelab instance and simplifies backups to "copy one file"). Map port 3000 for the web UI and port 22 (or a non-standard port if something else on the Pi already uses 22) for SSH-based git operations, and mount a persistent volume for Gitea's data directory so upgrades and container restarts don't lose your repositories.
First-Run Setup
Gitea's first-run wizard, reached at the mapped web port, walks through database configuration (or confirms SQLite), the server's public-facing domain/IP and SSH port, and creation of the first admin account. Disable public self-registration under the admin settings unless you specifically want this instance reachable by people signing up on their own — for a personal or small-team Git host, you want to create accounts manually and keep registration closed. From the admin panel, generate an application token if you plan to script against Gitea's API later (useful for automated repo creation or backup scripts).
Creating a Repository and Pushing
Create a new repository from the web UI, add your SSH public key to your Gitea user account under Settings, and clone or push to it exactly as you would to GitHub — `git remote add origin git@yourpi:username/reponame.git` followed by a normal `git push`. If you're migrating existing repositories from GitHub, Gitea has a built-in "migrate repository" tool that pulls history, issues, and (with a token) pull requests directly, which is faster than a manual clone-and-push-mirror for anything with real history you want preserved.
Reaching It Remotely: Reverse Proxy and Access
ApproachProsCons LAN-onlySimplest, no exposure riskCan't push from outside your network Tailscale / WireGuard VPNSecure remote access without opening portsRequires the VPN client on every device that pushes Nginx reverse proxy + Let's EncryptReal HTTPS domain, no VPN client neededYou're exposing a service to the internet — keep Gitea patched, disable registrationFor most home and small-team setups, pairing Gitea with a Tailscale-based Raspberry Pi VPN (covered elsewhere on this site) is the best balance of convenience and exposure risk — you get to `git push` from anywhere without opening inbound ports on your home router at all.
Backups
Gitea's own data directory (repositories, plus SQLite database if you're using it) is the entire state of the server; back it up the same way you'd back up any other self-hosted service on a Pi, ideally with the restic or Borg-based approach covered elsewhere on this site, pointed at the Docker volume path rather than trying to back up individual repos one at a time. Test a restore occasionally — a Git server whose backup has never been restored is not meaningfully backed up.
Closing Thoughts
A Gitea instance is a small, low-maintenance addition to a Raspberry Pi homelab that pays for itself the first time you need to recover an old firmware revision or push from a second machine without setting up cloud credentials. It's a genuinely different tool from a CI/CD runner even though both can involve the word "Gitea" — this is your git remote; a runner is what executes builds when you push to it, and you can add one on top of this setup later if you want automated testing on every commit.
Related Guides
- Self-Hosted CI/CD Runner on a Raspberry Pi: GitHub Actions and Gitea Actions
- Self-Hosting Jellyfin Media Server on a Raspberry Pi: Hardware Transcoding and Remote Access
- Raspberry Pi: Complete Headless Setup Guide (No Monitor Needed)
- How to Set Up a Raspberry Pi Headless with SSH and WiFi
- Linux Command Reference: Basic Usage & System Admin Commands
- Managing a Fleet of Raspberry Pis with Ansible: Automated Provisioning, Updates, and Config Management
- Backing Up Self-Hosted Services on Raspberry Pi with Restic and Borg
- Self-Hosting Syncthing on a Raspberry Pi: Real-Time File Sync Without the Cloud