All checks were successful
Deploy to NAS / deploy (push) Successful in 44s
- 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>
157 lines
4.5 KiB
Markdown
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 |
|