Some checks failed
Build and Push Docker Image / build-and-push (push) Has been cancelled
178 lines
6.1 KiB
Markdown
178 lines
6.1 KiB
Markdown
# Lageplan — CI/CD & Portainer Deployment
|
|
|
|
## Übersicht
|
|
|
|
```
|
|
┌─────────────┐ Push ┌─────────────────┐ Build + Push ┌─────────────────┐
|
|
│ Dein PC │ ────────────► │ Gitea (git) │ ──────────────────► │ Gitea Registry │
|
|
│ (VS Code) │ │ git.purepixel │ │ (Docker Image) │
|
|
└─────────────┘ └─────────────────┘ └────────┬────────┘
|
|
│
|
|
│ Pull
|
|
▼
|
|
┌─────────────────┐
|
|
│ Portainer │
|
|
│ (Stack Deploy) │
|
|
└─────────────────┘
|
|
```
|
|
|
|
1. **Push auf `main`** → Gitea Actions baut Docker Image
|
|
2. **Image wird gepusht** → Gitea Container Registry (`git.purepixel.ch`)
|
|
3. **Watchtower (in Portainer)** → prüft alle 60s auf neue Images und startet Container neu
|
|
|
|
---
|
|
|
|
## Voraussetzungen
|
|
|
|
- Gitea läuft mit Container Registry aktiviert
|
|
- Gitea Actions Runner ist registriert (`deploy/docker-compose.runner.yml`)
|
|
- Portainer Stack ist deployed mit korrekten Environment-Variablen
|
|
|
|
---
|
|
|
|
## Schritt 1: Gitea Container Registry aktivieren
|
|
|
|
In Gitea:
|
|
1. **Admin-Konsole** → **Konfiguration** → **Pakete**
|
|
2. **Container Registry** auf `Aktiviert` setzen
|
|
3. Speichern
|
|
|
|
Oder direkt in der `app.ini`:
|
|
```ini
|
|
[packages]
|
|
ENABLED = true
|
|
|
|
[package.container_registry]
|
|
ENABLED = true
|
|
```
|
|
|
|
---
|
|
|
|
## Schritt 2: Gitea Actions Runner registrieren
|
|
|
|
1. In Gitea: **Admin** → **Actions** → **Runners** → **Neuen Runner erstellen**
|
|
2. Token kopieren
|
|
3. In Portainer: Stack `gitea-runner` deployen mit [`deploy/docker-compose.runner.yml`](docker-compose.runner.yml)
|
|
4. Environment Variable `RUNNER_TOKEN` = das kopierte Token
|
|
|
|
---
|
|
|
|
## Schritt 3: Gitea Access Token erstellen
|
|
|
|
Das CI/CD Workflow braucht einen Token um Images in die Registry zu pushen:
|
|
|
|
1. Gitea → **Einstellungen** → **Anwendungen** → **Token erstellen**
|
|
2. Name: `registry-push`
|
|
3. Berechtigungen: `package:write` (mindestens)
|
|
4. Token kopieren und als **Repository Secret** hinterlegen:
|
|
- Repo → **Einstellungen** → **Secrets** → **Neues Secret**
|
|
- Name: `GITEA_TOKEN`
|
|
- Wert: das kopierte Token
|
|
|
|
---
|
|
|
|
## Schritt 4: Portainer Stack deployen
|
|
|
|
1. **Portainer** → `Stacks` → `+ Add stack`
|
|
2. **Name**: `lageplan`
|
|
3. **Build method**: `Repository`
|
|
4. **Git-URL**: `https://git.purepixel.ch/adminpepe/Lageplan.git`
|
|
5. **Compose path**: `docker-compose.portainer.yml`
|
|
6. **GitOps updates**: ✅ Aktivieren
|
|
7. **Mechanism**: `Webhook`
|
|
8. **Webhook URL kopieren** (für später)
|
|
|
|
### Environment Variables setzen:
|
|
|
|
| Variable | Wert | Beschreibung |
|
|
|----------|------|-------------|
|
|
| `POSTGRES_USER` | `lageplan` | DB User |
|
|
| `POSTGRES_PASSWORD` | *(sicheres Passwort)* | DB Passwort |
|
|
| `POSTGRES_DB` | `lageplan` | DB Name |
|
|
| `NEXTAUTH_URL` | `https://lageplan.ch` | Deine Domain |
|
|
| `NEXTAUTH_SECRET` | *(openssl rand -base64 32)* | Auth Secret |
|
|
| `MINIO_ROOT_USER` | `minioadmin` | MinIO User |
|
|
| `MINIO_ROOT_PASSWORD` | *(sicheres Passwort)* | MinIO Passwort |
|
|
| `MINIO_BUCKET` | `lageplan-icons` | Bucket Name |
|
|
| `MINIO_PUBLIC_URL` | `https://s3.deinedomain.ch` | MinIO externe URL |
|
|
| `GITEA_REGISTRY_USER` | `adminpepe` | Gitea User für Watchtower |
|
|
| `GITEA_REGISTRY_PASS` | *(Token oder Passwort)* | Gitea Passwort/Token |
|
|
|
|
9. **Deploy the stack**
|
|
|
|
---
|
|
|
|
## Schritt 5: Webhook in Gitea eintragen
|
|
|
|
Damit Portainer bei jedem Push automatisch neu deployed:
|
|
|
|
1. Gitea Repo → **Einstellungen** → **Webhooks** → **Neuer Webhook** → `Gitea`
|
|
2. **Ziel-URL**: Die kopierte Portainer Webhook URL
|
|
3. **HTTP-Methode**: `POST`
|
|
4. **Trigger**: Nur `Push events` (oder auch `Branch filter: main`)
|
|
5. **Webhook aktivieren** → Hinzufügen
|
|
|
|
---
|
|
|
|
## Schritt 6: Erstes Deployment testen
|
|
|
|
1. Lokal einen Push auf `main` machen:
|
|
```bash
|
|
git add .
|
|
git commit -m "Test CI/CD"
|
|
git push origin main
|
|
```
|
|
2. In Gitea: **Actions** Tab → Build-Job sollte laufen
|
|
3. Wenn grün → Image wurde in Registry gepusht
|
|
4. Watchtower (in Portainer) holt neues Image innerhalb von 60s
|
|
5. App ist unter `NEXTAUTH_URL` erreichbar
|
|
|
|
---
|
|
|
|
## Troubleshooting
|
|
|
|
### Gitea Actions startet nicht
|
|
- Prüfen ob Runner registriert ist: Gitea → Admin → Actions → Runners
|
|
- Runner muss `Idle` oder `Active` zeigen
|
|
|
|
### Image Push schlägt fehl (401 Unauthorized)
|
|
- `GITEA_TOKEN` Secret im Repo korrekt hinterlegt?
|
|
- Token hat Berechtigung `package:write`?
|
|
- Registry in Gitea aktiviert?
|
|
|
|
### Watchtower zieht kein neues Image
|
|
- `GITEA_REGISTRY_USER` und `GITEA_REGISTRY_PASS` in Portainer gesetzt?
|
|
- Image-Name in `docker-compose.portainer.yml` korrekt?
|
|
- Watchtower Logs prüfen: Portainer → Container `watchtower` → Logs
|
|
|
|
### App startet nicht / DB-Fehler
|
|
- Environment Variables in Portainer korrekt?
|
|
- `DATABASE_URL` wird automatisch gebaut, nur `POSTGRES_*` muss gesetzt werden
|
|
- Bei erstem Start: Prisma Migrations/Seed im Web-Container ausführen:
|
|
```bash
|
|
docker exec -it lageplan-web-1 npx prisma db push
|
|
docker exec -it lageplan-web-1 npx prisma db seed
|
|
```
|
|
|
|
---
|
|
|
|
## Manuelles Update (falls nötig)
|
|
|
|
Wenn Watchtower mal nicht greift:
|
|
```bash
|
|
# Auf dem Portainer-Host
|
|
docker pull git.purepixel.ch/adminpepe/lageplan:latest
|
|
docker compose -f docker-compose.portainer.yml up -d web
|
|
```
|
|
|
|
---
|
|
|
|
## Ports
|
|
|
|
| Service | Port | Extern? |
|
|
|---------|------|---------|
|
|
| Web App | 3000 | ✅ Ja (`WEB_PORT`) |
|
|
| PostgreSQL | 5432 | ❌ Nur intern |
|
|
| MinIO API | 9000 | ❌ Nur intern |
|
|
| MinIO Console | 9001 | ❌ Nur intern |
|