No description
Find a file
Repository files (latest commit first)
Filename Latest commit message Latest commit date
Christian Säum 2b5215d330
All checks were successful
CI – Validate & Release / validate (push) Successful in 9s
CI – Validate & Release / release (push) Has been skipped
Merge pull request 'chore(license): AGPL-3.0-or-later + Copyright-Hinweis' (#4) from chore/add-license into main
2026-09-02 19:47:23 +00:00
.forgejo/workflows chore: remove Codeberg mirror job from CI 2026-08-02 11:55:40 +02:00
.idea feat: initial imagor stack for AI image labeling 2026-08-02 11:36:23 +02:00
.env docs: document secret generation for IMAGOR_SECRET 2026-08-02 13:28:42 +02:00
.gitignore feat: initial imagor stack for AI image labeling 2026-08-02 11:36:23 +02:00
AGENTS.md feat: initial imagor stack for AI image labeling 2026-08-02 11:36:23 +02:00
CICD-Actions.md chore: remove Codeberg mirror job from CI 2026-08-02 11:55:40 +02:00
CLAUDE.md feat: initial imagor stack for AI image labeling 2026-08-02 11:36:23 +02:00
docker-compose.yml fix: use curl instead of wget for imagor healthcheck 2026-08-02 13:40:20 +02:00
LICENSE chore(license): add AGPL-3.0-or-later license and copyright notice 2026-09-02 21:32:17 +02:00
Projekt.md feat: initial imagor stack for AI image labeling 2026-08-02 11:36:23 +02:00
README.md chore(license): add AGPL-3.0-or-later license and copyright notice 2026-09-02 21:32:17 +02:00

imagor – Bildauslieferung für die KI-Bildkennzeichnung

imagor liefert Produktbilder für den Shopware-6-Shop aus und versieht dabei KI-generierte bzw. -veränderte Bilder mit einem sichtbaren deutschen Text-Wasserzeichen (Art. 50 Abs. 4 KI-VO). Das Plugin WSC_SWPlugin_AiSeoTools (ImagorUrlBuilder) baut die URLs, die hier ankommen.

Template-Hinweis: Konfiguration läuft über die .env. Vor dem Einsatz ALLE CHANGE_ME-Platzhalter ersetzen (HOSTRULE, HTTP_LOADER_ALLOWED_SOURCES, IMAGOR_SECRET).


Voraussetzungen

  • Docker & Docker Compose v2
  • Traefik-Stack (docker-traefik-proxy) läuft bereits und stellt das externe Netzwerk traefik_proxy_network bereit
  • Der Shop (projekt-sw6) ist öffentlich per HTTPS erreichbar (imagor holt Quellbilder per HTTP, kein Shared-Volume nötig)

Verzeichnisstruktur

docker-imagor-media/
├── .env                ← Konfiguration (Domain, Allowlist, Image-Tag)
├── docker-compose.yml  ← imagor Stack-Datei
└── README.md

Stack starten

docker compose up -d

Konfiguration

Alle Einstellungen werden über die .env gesetzt und in der docker-compose.yml als ${VARIABLE} referenziert.

Variable (.env) Default/Platzhalter Beschreibung
IMAGOR_IMAGE_TAG 1.9.3 Gepinnte Image-Version (letzte benannte Release)
HOSTRULE Host(\img.CHANGE_ME....`)` Traefik-Routing-Regel, echte Subdomain eintragen
PROXY_NETWORK traefik_proxy_network Name des externen Traefik-Netzwerks
HTTP_LOADER_ALLOWED_SOURCES CHANGE_ME.example.com Erlaubte Quell-Hosts für Bilder (glob, csv) — sicherheitsrelevant (SSRF)
IMAGOR_LOAD_TIMEOUT 30s Timeout beim Laden von Quellbildern
RESULT_STORAGE_EXPIRATION 168h Wie lange gecachte Bild-Varianten aufbewahrt werden
IMAGOR_SECRET CHANGE_ME Aktuell unbenutzt (siehe "Bekannte Einschränkung" unten)

Sicherheit: HTTP-Loader-Allowlist & SSRF-Schutz

imagor holt Quellbilder per HTTP nach HTTP_LOADER_ALLOWED_SOURCES — ohne Einschränkung wäre imagor ein offener URL-Proxy (SSRF-Risiko). Der Stack setzt deshalb zusätzlich:

  • HTTP_LOADER_BLOCK_LOOPBACK_NETWORKS=1 (blockiert 127.0.0.1/::1)
  • HTTP_LOADER_BLOCK_PRIVATE_NETWORKS=1 (blockiert 10.x.x.x, 192.168.x.x, …)
  • HTTP_LOADER_BLOCK_LINK_LOCAL_NETWORKS=1 (blockiert 169.254.x.x)

HTTP_LOADER_ALLOWED_SOURCES muss vor dem produktiven Einsatz auf die echte(n) Shop-Domain(s) gesetzt werden — nicht auf * oder leer lassen.


Bekannte Einschränkung: Unsafe-Modus

IMAGOR_UNSAFE=1 ist aktuell aktiv, weil ImagorUrlBuilder im Plugin WSC_SWPlugin_AiSeoTools noch keine signierten URLs baut (dort im Code als bewusste, dokumentierte Vereinfachung markiert). Das bedeutet: jeder, der die Bild-Pfad-Struktur kennt, kann beliebige Transformationen der erlaubten Quellbilder anfordern (kein Zugriff auf fremde Daten, aber zusätzliche Rechenlast wäre theoretisch erzwingbar).

Nicht im Alleingang auf signierte URLs (IMAGOR_SECRET) umstellen — das würde alle Anfragen des Plugins sofort brechen. Eine Umstellung ist eine koordinierte Änderung in beiden Repos (hier: IMAGOR_UNSAFE entfernen + echten IMAGOR_SECRET setzen; im Plugin: ImagorUrlBuilder um HMAC-Signierung erweitern).


Nützliche Befehle

# Stack starten
docker compose up -d

# Stack stoppen
docker compose down

# Logs verfolgen
docker logs -f imagor

# Beispiel-Request gegen eine erlaubte Quelle (unsafe-Modus)
curl -I "https://img.example.com/unsafe/400x400/shop.example.com/media/xy/bild.jpg"

Troubleshooting

403/Fehler beim Laden von Quellbildern:

  • Prüfen ob die Domain in HTTP_LOADER_ALLOWED_SOURCES eingetragen ist
  • Prüfen ob die Quell-URL wirklich per HTTPS öffentlich erreichbar ist

Traefik liefert 404 für die imagor-Domain:

  • HOSTRULE in der .env prüfen (echte Domain statt CHANGE_ME)
  • Prüfen ob docker-traefik-proxy läuft und traefik_proxy_network existiert: docker network ls | grep traefik_proxy_network

Ergebnis-Bilder wirken nicht aktualisiert:

  • Gecachte Result-Storage-Variante ist noch nicht abgelaufen (RESULT_STORAGE_EXPIRATION) — Cache-Ordner liegt unter ./volumes/result

CI/CD

Die Pipeline (.forgejo/workflows/ci.yml) läuft self-hosted auf Forgejo, ganz ohne externe Actions (Checkout per git clone). Anders als bei den Nachbar-Stacks gibt es hier keinen Code-Mirror nach Codeberg:

  • 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.
  • 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.