← Back to Blog

Self-Hosted Git with Gitea on Unraid

By Charles

After building several apps and automation projects, we needed a Git hosting solution that we fully control. GitHub is great, but when you’re running a homelab with private configs, API keys referenced in code, and projects that aren’t ready for public eyes, self-hosting makes sense.

Why Gitea?

We evaluated a few options:

SolutionProsCons
GiteaLightweight, Go binary, low RAMFewer features than GitLab
GitLab CEFull CI/CD, registry4GB+ RAM, complex
ForgejoGitea fork, community-drivenSmaller ecosystem
GogsMinimalStale development

Gitea won because it runs on under 200MB of RAM, starts in seconds, and has a GitHub-like UI that’s immediately familiar. It also has a full REST API, which matters when you’re automating with scripts.

Setup on Unraid

The Unraid Community Apps store has a Gitea template. The key settings:

Container: gitea/gitea:latest
Port: custom HTTP port, custom SSH port
AppData: /mnt/user/appdata/gitea
Database: SQLite (good enough for personal use)

SQLite is fine for a single-user or small-team setup. You’d only need PostgreSQL or MySQL if you’re expecting dozens of concurrent users.

After starting the container, hit http://server-ip:<your-port> to run the initial setup wizard. Create your admin account, and you’re done.

Repository Structure

We ended up with this repo layout:

Claude/homeassistant    (private) - HA configs, automations, dashboards
Claude/esp32            (private) - ESPHome templates, PlatformIO starters
Claude/website          (public)  - This portfolio site (Astro + Tailwind)
Claude/dblog            (public)  - Noise complaint tracker app
Claude/homekeep         (private) - Home maintenance tracker app
Claude/salefinder       (private) - Garage sale finder app
Claude/wifi-share-releases (public) - WiFi QR code app
Claude/subwatch         (private) - Subscription tracker app

Private repos for anything with configs, keys, or unreleased code. Public repos for apps that are heading to the Play Store.

Git Credential Setup

Instead of entering credentials every push, set up a credential helper:

git config --global credential.helper store

Then create ~/.git-credentials with your Gitea token:

http://your-username:your-token@server-ip:<your-port>

Generate the token in Gitea under Settings > Applications > Generate New Token.

API-Driven Repo Creation

One thing we use heavily is the Gitea API for creating repos from scripts:

curl -s -X POST "http://server-ip:<your-port>/api/v1/user/repos" \
  -H "Authorization: token YOUR_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "name": "my-project",
    "description": "Project description",
    "private": true,
    "default_branch": "main"
  }'

This is useful when you’re initializing projects programmatically. Create the repo, add the remote, push — all in one script.

Backup Strategy

Gitea stores everything in its appdata directory:

  • gitea/ - Configuration, database
  • git/repositories/ - Bare git repos

Since this lives on Unraid, it’s covered by the array’s parity protection. For off-site backup, you could:

  1. rsync the appdata to another machine
  2. Mirror repos to GitHub/GitLab as a secondary remote
  3. Unraid’s built-in backup to an external drive

We use option 2 for public repos — push to both Gitea (primary) and GitHub (mirror).

What We’d Do Differently

Start with Gitea from day one. We initially had code scattered across local directories with no version control. Retroactively adding git to existing projects means messy initial commits. If you’re starting a homelab, set up Gitea before you write any config files.

Use SSH keys instead of HTTP tokens. We started with HTTP for simplicity, but SSH keys are more secure and don’t need credential files sitting on disk.

Set up webhooks early. Gitea supports webhooks that can trigger builds, deployments, or notifications on push. We’re planning to hook this into our website deployment pipeline.

The Result

8 repositories, all version-controlled, all backed up by Unraid’s parity. Private repos for sensitive configs, public repos for apps heading to the Play Store. Total resource usage: ~150MB RAM, negligible CPU. For a homelab, that’s the right answer.


Resources

  • Unraid OS — Runs Gitea (and 25+ other containers) with parity-protected storage. The Community Apps store has a one-click Gitea template.
  • Gitea — Free, self-hosted Git service. Lightweight alternative to GitLab that runs on under 200MB of RAM.