No description
Find a file
Repository files (latest commit first)
Filename Latest commit message Latest commit date
Christian Säum dc4a4cfd34
All checks were successful
CI – Validate & Release / validate (push) Successful in 11s
CI – Validate & Release / mirror (push) Successful in 2s
CI – Validate & Release / release (push) Has been skipped
Merge pull request 'chore(license): AGPL-3.0-or-later + Copyright-Hinweis' (#1) from chore/add-license into main
2026-09-02 19:47:25 +00:00
.forgejo/workflows fix(ci): retry Codeberg pushes on 502/504, prefer compose v2 2026-06-21 18:48:54 +02:00
.idea feat(ofelia): reusable cronjob scheduler template 2026-06-13 13:32:04 +02:00
.env feat(ofelia): reusable cronjob scheduler template 2026-06-13 13:32:04 +02:00
.gitignore chore(gitignore): ignore dist/ (CI build artifacts) 2026-06-21 14:30:14 +02:00
AGENTS.md feat(ofelia): reusable cronjob scheduler template 2026-06-13 13:32:04 +02:00
CICD-Actions.md docs(ci): align docs with hardened pipeline (compose v2 runner image, Codeberg 502/504 retry) 2026-06-21 18:57:48 +02:00
CLAUDE.md feat(ofelia): reusable cronjob scheduler template 2026-06-13 13:32:04 +02:00
docker-compose.yml feat(ofelia): reusable cronjob scheduler template 2026-06-13 13:32:04 +02:00
LICENSE chore(license): add AGPL-3.0-or-later license and copyright notice 2026-09-02 21:32:24 +02:00
Projekt.md feat(ofelia): reusable cronjob scheduler template 2026-06-13 13:32:04 +02:00
README.md chore(license): add AGPL-3.0-or-later license and copyright notice 2026-09-02 21:32:24 +02:00

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 compose immer 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 hat ofelia.enabled: "true"?
  • docker logs ofelia zeigt beim Start die erkannten Jobs.

Cleanup löscht nichts / Reports fehlen:

  • docker compose aus 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 auf main + Tags): docker compose config -q, yamllint (relaxed) und gitleaks (nur Working-Tree). Es wird docker compose v2 genutzt (Runner-Image catthehacker/ubuntu:act-latest; nötig u. a. für v2-Keys wie dockerfile_inline), apt nur als Fallback – kein 64-MB-github-Download.
  • mirror (nur Push, needs: validate): spiegelt main + Tags erst nach grünen Checks nach Codeberg (Org Docker-Stacks), mit Retry gegen transiente 502/504. Forgejos eingebauten Push-Mirror dafür nicht zusätzlich aktivieren.
  • release (nur Tag v*): 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.