| Filename | Latest commit message | Latest commit date |
|---|---|---|
| .forgejo/workflows | ||
| .idea | ||
| .env | ||
| .gitignore | ||
| AGENTS.md | ||
| CICD-Actions.md | ||
| CLAUDE.md | ||
| docker-compose.yml | ||
| LICENSE | ||
| Projekt.md | ||
| README.md | ||
Ofelia – Zentrale CronJobs (Stack-Template)
Ofelia ist ein Job-Scheduler für Docker (Cron-Ersatz).
Jobs werden über Docker-Labels definiert und zeitgesteuert ausgeführt. Dieser Stack läuft
als Daemon (--docker) und bringt nur einen Cleanup-Job für die eigenen Log-Reports mit –
weitere Jobs fügst du per Label hinzu.
1. Voraussetzungen
- Docker + Docker Compose v2
- Zugriff auf den Docker-Socket (
/var/run/docker.sock)
2. Starten
Wichtig:
docker composeimmer aus diesem Stack-Verzeichnis starten. Die Mounts nutzen${PWD}/logs, damit Daemon und Cleanup-Job exakt dasselbe Host-Verzeichnis treffen.
docker compose up -d
Der Ordner logs/ wird automatisch angelegt (ist in .gitignore).
3. Job-Logs / Fehlersuche
- Ofelia speichert Job-Reports als Datei in
logs/(save-folder). save-only-on-error: true→ es werden nur Reports von fehlgeschlagenen Jobs geschrieben. So bleibt das Verzeichnis schlank und enthält genau das, was für die Fehlersuche zählt.- Der Cleanup-Job löscht Reports, die älter als 6 h sind (alle 6 h).
- Das Betriebs-Log des Daemons selbst läuft über
docker logs ofelia(json-file, rotiert).
4. Eigene Jobs hinzufügen
Es gibt zwei Job-Typen – wähle nach Zweck:
job-run – isolierter, kurzlebiger Container
Für eigenständige Tasks. Jeder Lauf bekommt einen frischen, eigenen Container aus
einem Image → vollständig isoliert, kein geteilter Zustand mit anderen Jobs.
Labels gehören auf den ofelia-Container (er startet ja den neuen Container):
labels:
ofelia.job-run.mein-task.schedule: "0 0 3 * * *" # taeglich 03:00:00 (6-Feld!)
ofelia.job-run.mein-task.image: "alpine:3.21"
ofelia.job-run.mein-task.command: "sh -c 'echo hallo'"
ofelia.job-run.mein-task.volume: '["/abs/host/pfad:/data"]'
job-exec – Befehl in einem bestehenden Container
Für Befehle in einem bereits laufenden Service-Container (z. B. mysqldump im DB-Container,
bin/console … im App-Container). Labels gehören auf den Ziel-Container, plus
ofelia.enabled: "true":
services:
datenbank:
image: mariadb:11
labels:
ofelia.enabled: "true"
ofelia.job-exec.backup.schedule: "0 30 2 * * *" # taeglich 02:30:00
ofelia.job-exec.backup.command: "sh -c 'mysqldump ... > /backup/dump.sql'"
5. Schedule-Format (wichtig!)
Ofelia nutzt 6-Feld-Cron mit Sekunden (nicht 5 Felder!):
┌───────────── Sekunde (0-59)
│ ┌─────────── Minute (0-59)
│ │ ┌───────── Stunde (0-23)
│ │ │ ┌─────── Tag des Monats (1-31)
│ │ │ │ ┌───── Monat (1-12)
│ │ │ │ │ ┌─── Wochentag (0-6)
│ │ │ │ │ │
0 0 */6 * * * → alle 6 Stunden (00/06/12/18 Uhr)
Alternativ die Kurzform: @every 6h, @daily, @hourly.
6. Nützliche Befehle
docker compose config -q # Konfiguration validieren
docker compose up -d # Starten
docker logs -f ofelia # Daemon-Log (zeigt geplante/ausgeführte Jobs)
ls -la logs/ # Gespeicherte Fehler-Reports ansehen
docker compose down # Stoppen
7. Troubleshooting
Job läuft nicht:
- Schedule wirklich 6-Feld (mit Sekunden)? Siehe Abschnitt 5.
- Bei
job-exec: Ziel-Container hatofelia.enabled: "true"? docker logs ofeliazeigt beim Start die erkannten Jobs.
Cleanup löscht nichts / Reports fehlen:
docker composeaus dem Stack-Verzeichnis gestartet? (${PWD}/logs)save-only-on-error: true→ bei erfolgreichen Jobs entstehen bewusst keine Reports.
8. CI/CD & Spiegelung
Die Pipeline (.forgejo/workflows/ci.yml) läuft self-hosted auf Forgejo, ganz ohne externe Actions (Checkout per git clone):
validate(jeder Push/PR aufmain+ Tags):docker compose config -q,yamllint(relaxed) undgitleaks(nur Working-Tree). Es wird docker compose v2 genutzt (Runner-Imagecatthehacker/ubuntu:act-latest; nötig u. a. für v2-Keys wiedockerfile_inline), apt nur als Fallback – kein 64-MB-github-Download.mirror(nur Push,needs: validate): spiegeltmain+ Tags erst nach grünen Checks nach Codeberg (OrgDocker-Stacks), mit Retry gegen transiente 502/504. Forgejos eingebauten Push-Mirror dafür nicht zusätzlich aktivieren.release(nur Tagv*): baut ein schlankes Deploy-ZIP und hängt es an ein Forgejo-Release und – als Backup – an ein Codeberg-Release (die Releases-Unit am Codeberg-Repo wird dabei automatisch aktiviert).
Release auslösen:
git tag v1.1
git push origin v1.1
Details siehe CICD-Actions.md.
Lizenz
Copyright (C) 2026 Christian Säum – web-seo-consulting.eu
Dieses Projekt steht unter der GNU Affero General Public License, Version 3
oder (nach deiner Wahl) einer späteren Version (AGPL-3.0-or-later). Der
vollständige Lizenztext steht in der Datei LICENSE.
Du darfst die Software nutzen, weitergeben und – auch kommerziell – verkaufen.
Gibst du eine veränderte Fassung weiter oder betreibst du sie über ein
Netzwerk (z. B. als Dienst), muss deren vollständiger Quellcode ebenfalls
unter der AGPL-3.0-or-later verfügbar sein. Der Copyright-Hinweis und die
Nennung des ursprünglichen Autors dürfen nicht entfernt werden.
Diese Angabe betrifft nur die in diesem Repository enthaltenen eigenen Dateien (Konfiguration, Skripte, Anpassungen). Eingebundene Fremdsoftware und Container-Images unterliegen weiterhin ihren eigenen Lizenzen.