feature: Add Gitea docs

This commit is contained in:
Keith Solomon
2025-11-30 21:24:04 -06:00
parent 9291b641da
commit 474a967a24
7 changed files with 684 additions and 0 deletions

254
content/soloforge-docs.md Normal file
View File

@@ -0,0 +1,254 @@
---
title: SoloForge Documentation
section: docs
summary: SoloForge Infrastructure Documentation for Self-Hosted Gitea with Actions Runner on Hetzner
tags: [servers, infrasctructure, gitea, ci/cd, hetzner, docker]
nav: 1
---
## Self-Hosted Gitea + Actions Runner (Hetzner Deployment)
This document describes the current SoloForge setup — Gitea, Traefik routing, the Gitea Actions runner, backup routines, directory layout, and operational notes.
This repo exists so future-me (and actual-me) dont need to reverse-engineer anything when something eventually explodes.
## 1. Overview
SoloForge is a self-hosted Gitea instance running on a Hetzner VM.
It provides:
- Private (but login-protected) Git hosting
- Public-visible repositories (instance auth is required anyway)
- Gitea Actions, backed by a Docker-based self-hosted runner
- Automatic CI for TODO-to-issue sync and other workflows
- Reverse-proxy via Traefik
- Automated Gitea backups
The system replaces the original Proxmox-hosted Gitea instance lost due to disk failure.
---
## 2. System Layout
### Hetzner VM
- Debian 13
- Docker + Docker Compose installed
- Traefik reverse proxy (existing before SoloForge migration)
- HTTPS termination handled by Traefik via Lets Encrypt
### Directory structure
```bash
/gitea/
├── gitea/ # Gitea app + persistent data
├── postgres/ # PostgreSQL data directory (if using Postgres)
└── docker-compose.yml # Main Gitea stack
```
### Runner lives separately
```bash
/gitea/gitea-runner/
├── docker-compose.yml # Actions runner stack
└── data/ # Contains .runner registration + job cache
```
---
## 3. Gitea Deployment
### 3.1 Gitea Compose Service
Gitea is launched via Docker Compose and reverse-proxied through Traefik.
Data lives under `/gitea/gitea` to ensure persistence.
### 3.2 Traefik Routing
Traefik handles:
- HTTPS certificate generation
- Routing git.keithsolomon.net → Gitea web UI
- Exposing SSH port (222) for git-over-SSH
No YAML generator required anymore — everything is stable and hand-maintained.
---
## 4. Gitea Actions Runner
SoloForge uses a self-hosted Gitea Actions runner, running via Docker and capable of executing JavaScript (Node-based) GitHub-style actions.
### 4.1 Runner compose file
Located at:
`/gitea/gitea-runner/docker-compose.yml`
Core configuration:
```yaml
environment:
GITEA_INSTANCE_URL: "https://git.keithsolomon.net"
GITEA_RUNNER_REGISTRATION_TOKEN: "<token>"
GITEA_RUNNER_NAME: "hetzner-runner-1"
GITEA_RUNNER_LABELS: "ubuntu-latest:docker://node:20-bullseye,self-hosted,linux,x86_64,docker"
```
By default, GitHub runners provide Node.js preinstalled.
Self-hosted runners do NOT.
Mapping:
`ubuntu-latest:docker://node:20-bullseye`
ensures any workflow using:
```yaml
runs-on: ubuntu-latest
```
runs inside a Node-enabled container, fixing "node: command not found" errors.
### 4.3 Re-registering the runner (important!)
If labels change or the runner breaks:
```bash
cd /gitea/gitea-runner
docker compose down
rm -f data/.runner # Forces new registration
docker compose up -d # Registers with current labels
```
Check runner status in Gitea:
**Site Admin → Actions → Runners**
---
## 5. Workflows
### 5.1 TODO-to-Issue Sync
Certain repos use a custom JavaScript action to:
- Parse TODO comments
- Generate/close GitHub-style issues inside Gitea
These workflows run cleanly now because:
- The runner supports Node (ubuntu-latest → node:20 container)
- Repository permissions allow issue writing
### 5.2 Secret tokens
Unlike GitHub, Gitea does not auto-inject GITHUB_TOKEN.
Workflows requiring an auth token need one defined manually in:
**Repo → Settings → Secrets**
Example:
`GITHUB_TOKEN = <personal access token>`
(Or rename to something more Gitea-themed.)
---
## 6. Repository Management
### 6.1 Bulk import
All repos were migrated using a [custom bulk-mirror script](/assets/files/gitea/git-bulk) that:
- Created missing repos via the Gitea API
- Pushed full history via git push --all and --tags
### 6.2 Public visibility
All repos are public (since Gitea login protects everything).
A [bulk-update script](/assets/files/gitea/git-flip) is available to flip visibility via API if needed.
---
## 7. Backups
Gitea supports built-in dumps via:
`gitea dump`
A cronjob is installed to dump nightly at 3am:
```bash
/gitea-backups/
└── gitea-dump-YYYYMMDD.zip
```
Recommended: sync this folder offsite or back to home lab.
---
## 8. Restore Notes
If Gitea must be restored from dump:
```bash
docker compose down
rm -rf gitea/* postgres/*
unzip gitea-dump.zip into /gitea/gitea
docker compose up -d
```
If the runner needs re-registration, follow section 4.3.
---
## 9. Future Improvements (Optional)
- Mirror “source of truth” repos between GitHub ↔ Gitea
- Add automated org-level secrets
- Configure multiple runners (home lab, Hetzner, etc.)
- Add Prometheus metrics + Grafana board for CI activity
- Set up Giteas dependency listing or vulnerability scanning
---
## 10. `forge` CLI Tool
A custom CLI tool [`forge`](/assets/files/gitea/forge) exists to help manage common tasks:
| Command | Description |
| --------------------------- | ---------------------------------------------------------- |
| `forge status` | Show status of Gitea and runner containers |
| `forge ps` | Alias for status |
| `forge gitea-logs` | Tail logs from Gitea container |
| `forge runner-logs` | Tail logs from Actions runner container |
| `forge backup` | Run a Gitea dump and move it into BACKUP_DIR |
| `forge restart-gitea` | Restart Gitea stack |
| `forge restart-runner` | Restart Actions runner stack |
| `forge runner-reset` | Re-register runner with current labels (destroys .runner) |
| `forge diag` | Quick diagnostic summary |
## TL;DR Cheat Sheet
### Runner broke?
`→ delete data/.runner, docker compose up -d`
### `node` not found?
`→ ensure ubuntu-latest label is mapped to node:20-bullseye`
### Release workflows failing?
`→ they're GitHub-only; they run on GitHub mirrors`
### Backup?
`→ see /gitea-backups, nightly gitea dump`
### Repo not found?
`→ bulk import script: auto-create + push mirror`