Files
pamietnik/infra/gitea-actions.md
Christoph K. ad65102fdc
All checks were successful
Deploy to NAS / deploy (push) Successful in 44s
Update infra docs with complete working setup
- README.md: rewrite with accurate setup steps including all lessons learned
- CLAUDE.md: update with working CI/CD patterns and known pitfalls
- gitea-actions.md: new file documenting Gitea Actions usage, expressions,
  act_runner config, and troubleshooting for future projects

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-07 18:46:55 +02:00

157 lines
4.5 KiB
Markdown

# Gitea Actions — Verwendung & Referenz
## Grundprinzip
Gitea Actions ist kompatibel mit GitHub Actions Syntax. Workflow-Dateien liegen in `.gitea/workflows/*.yml` im Repository. Bei Push auf `main` wird der Workflow automatisch ausgeführt.
```
Push → Gitea → act_runner auf NAS → Job-Container (docker:latest) → Deploy
```
---
## Workflow-Struktur
```yaml
name: Deploy to NAS # Anzeigename in Gitea UI
on:
push:
branches: [main] # Trigger: Push auf main
jobs:
deploy: # Job-Name
runs-on: self-hosted # Welcher Runner-Typ
container:
image: docker:latest # Job läuft in diesem Container
options: -v /volume2/docker:/volume2/docker # Volume-Mounts
steps:
- name: Schritt 1
run: echo "Shell-Befehl"
- name: Schritt 2
run: |
echo "Mehrzeiliger"
echo "Shell-Block"
```
---
## Expressions
Werte aus Gitea zur Laufzeit einsetzen:
| Expression | Quelle | Beispiel |
|------------|--------|---------|
| `${{ secrets.NAME }}` | Secrets (maskiert in Logs) | `${{ secrets.DB_PASSWORD }}` |
| `${{ vars.NAME }}` | Variables (sichtbar in Logs) | `${{ vars.DEPLOY_DIR }}` |
| `${{ github.repository }}` | Repo-Metadaten | `christoph/pamietnik` |
| `${{ github.sha }}` | Aktueller Commit-Hash | `abc1234...` |
**Secrets vs Variables:**
- **Secrets** → Passwörter, Tokens, API-Keys (`secrets.NAME`)
- **Variables** → Pfade, Ports, Namen, alles Nicht-Sensible (`vars.NAME`)
Setzen unter: **Repository → Einstellungen → Actions → Secrets / Variables**
---
## act_runner auf der NAS
Der Runner empfängt Jobs von Gitea und führt sie aus.
### Laufender Container
```bash
sudo docker ps | grep gitea-runner
sudo docker logs gitea-runner -f # Live-Logs
```
### Konfiguration
`/volume2/docker/gitea-runner/config.yaml`:
```yaml
runner:
name: "nas-runner"
container:
valid_volumes:
- /volume2/docker # Erlaubt Volume-Mounts in Job-Containern
```
### Wichtige Einschränkungen auf Synology
- `GITEA_INSTANCE_URL` muss NAS-IP sein (`192.168.1.4:3000`), **nicht** `localhost`
→ Job-Container sehen `localhost` als sich selbst, nicht als NAS
- Docker-Socket wird automatisch in Job-Container propagiert
**nicht** nochmals in `container.options` mounten (→ Duplicate-Fehler)
- `valid_volumes` in `config.yaml` pflegen, sonst werden Mounts ignoriert
---
## Job-Container: docker:latest
Für Deployments wird `docker:latest` als Job-Container verwendet:
```yaml
container:
image: docker:latest
options: -v /volume2/docker:/volume2/docker
```
**Was ist enthalten:**
- Docker CLI (`docker`, `docker compose`)
- `wget`, `sh`, `git`
- **Nicht enthalten:** `curl`, `bash` (nur `sh`)
**Volume-Mount `-v /volume2/docker:/volume2/docker`:**
Macht den NAS-Dateipfad im Container verfügbar — notwendig damit git clone, .env schreiben und docker compose auf die richtigen Dateien zugreifen.
---
## Secrets & Variables anlegen
**Gitea UI:**
1. Repository → Einstellungen → Actions
2. "Secrets" für Passwörter/Tokens → `secrets.NAME`
3. "Variables" für Konfiguration → `vars.NAME`
**Typische Variablen pro Projekt:**
| Name | Typ | Beispielwert |
|------|-----|-------------|
| `DEPLOY_DIR` | Variable | `/volume2/docker/pamietnik` |
| `APP_PORT` | Variable | `9050` |
| `DB_USER` | Variable | `pamietnik` |
| `DB_NAME` | Variable | `pamietnik` |
| `DB_PASSWORD` | Secret | `<passwort>` |
> **Achtung:** Keine Leerzeichen am Ende von Variable-Werten — führt zu Parsing-Fehlern in Expressions.
---
## Workflow-Status überwachen
**Gitea UI:** Repository → Actions → laufenden/letzten Job anklicken
**Runner-Logs live:**
```bash
sudo docker logs gitea-runner -f
```
**Job neu triggern (leerer Commit):**
```bash
git commit --allow-empty -m "ci: retrigger deploy" && git push
```
---
## Fehlersuche
| Fehler | Ursache | Lösung |
|--------|---------|--------|
| `connection refused :3000` | `localhost` statt NAS-IP | `GITEA_INSTANCE_URL=http://192.168.1.4:3000` |
| `Duplicate mount point` | Socket doppelt gemountet | Nur einmal in `container.options` oder nur Runner-Mount |
| `not a valid volume, will be ignored` | `valid_volumes` fehlt | In `config.yaml` eintragen |
| `curl: not found` | nicht in docker:latest | `wget -qO-` verwenden |
| `cannot find node in PATH` | `actions/checkout@v4` braucht Node | Stattdessen `git clone/pull` direkt verwenden |
| Variable leer (`/docker-compose.yml`) | Als Secret statt Variable gesetzt | Unter Variables (nicht Secrets) anlegen |