Files
Photography/Brain.md
Kroonk 64fe667240
All checks were successful
Build & Push Docker Image to Gitea Registry / build-and-push (push) Successful in 33s
Fix Photography deploy metadata and SQLite migration
2026-05-20 18:54:10 +02:00

9.4 KiB

Brain.md - Projekt-Wissensdatenbank

Projektziel

Eine eigene Fotografie-Portfolio-Website basierend auf dem Template von rampatra/photography. Keine 1:1 Kopie, sondern eine individuell angepasste Version mit eigenen Anspruechen.

Besitzer & Kontakt


Technologie-Stack

Komponente Technologie
Static Site Generator Jekyll (Ruby-basiert)
Backend Node.js / Express (Auth, API, Static Serving)
Datenbank SQLite (Nutzerverwaltung, Bildzuweisung)
Templating Liquid Templates
Styling SCSS -> kompiliertes CSS
JS Libraries jQuery, Poptrox (Lightbox), EXIF.js
Build-Tool Gulp (SCSS kompilieren, JS minifizieren, Bilder resizen)
Hosting UGREEN NAS (Docker) via Node.js Express
Containerisierung Docker Multi-Stage (Jekyll Build + Node.js Backend)
Auto-Update Watchtower (prueft alle 5 Min auf neue Images)
Fonts FontAwesome, Google Fonts (Source Sans Pro)
Paketmanager npm (Node), Bundler (Ruby)

Projektstruktur

Photography/
├── _config.yml          # Zentrale Konfiguration (Titel, Social Links, EXIF etc.)
├── _layouts/
│   └── default.html     # Basis-Layout (Head + Body + Scripts)
├── _includes/
│   ├── header.html      # <head> Bereich: CSS, Fonts
│   └── footer.html      # Script-Einbindungen (jQuery, Poptrox, EXIF, Main)
├── index.html           # Hauptseite: Header, Galerie-Grid, Footer/About, Login-Panel
├── admin.html           # Admin-Dashboard (Nutzerverwaltung, Bildzuweisung)
├── backend/
│   ├── server.js        # Express Backend (Auth, API, Static Files, Port 8090)
│   └── database.js      # SQLite Datenbank-Setup (Users, User-Images)
├── assets/
│   ├── css/             # Kompilierte CSS-Dateien (.min.css)
│   ├── sass/            # SCSS Quelldateien
│   │   ├── base/        # Reset, Typography, Page
│   │   ├── components/  # Buttons, Forms, Icons, Panels, Poptrox
│   │   ├── layout/      # Header, Footer, Main, Wrapper
│   │   └── libs/        # Breakpoints, Mixins, Vars, Functions
│   ├── js/              # JavaScript (jQuery, Poptrox, EXIF, Main, Admin)
│   ├── fonts/           # FontAwesome Fonts
│   └── webfonts/        # FA5 Webfonts
├── images/
│   ├── fulls/           # Vollaufloesung Bilder
│   └── thumbs/          # Thumbnails (512px)
├── gulpfile.mjs         # Build: SCSS->CSS, JS minify, Image resize
├── package.json         # Node Dependencies (Express, SQLite, JWT, bcrypt)
├── Gemfile              # Ruby Dependencies (jekyll)
├── Dockerfile           # Multi-Stage: Jekyll Build + Node.js Runtime
├── docker-compose.yml   # Container + Watchtower
├── entrypoint.sh        # Thumbnail-Generierung + Node.js Start
└── nginx.conf           # (Legacy, nicht mehr aktiv - Express dient statische Dateien)

Wie die Galerie funktioniert (Dynamisch)

  1. Bilder hochladen: Fotos in Nextcloud-Ordner Websitebilder ablegen
  2. Volume-Mount: Docker mountet den Nextcloud-Ordner als /app/public/images/fulls/ (read-only)
  3. Thumbnails: entrypoint.sh generiert automatisch 512px Thumbnails via ImageMagick
  4. Thumbnail-Check: Alle 60 Sekunden prueft der Container auf neue Bilder
  5. Express API: /images/fulls/ liefert JSON-Liste der Bilddateien
  6. JavaScript (main.js): Fetcht die JSON-Liste und baut dynamisch <article class="thumb"> Elemente
  7. Poptrox-Lightbox: Klick oeffnet Vollbild + EXIF-Daten (clientseitig via exif.js)
  8. Download-Button: In der Lightbox kann jedes Bild heruntergeladen werden

Zugriffslogik

  • Nicht eingeloggt: Nur Root-Bilder (direkt in Websitebilder/) sichtbar
  • Admin: Alle Bilder (Root + alle Unterordner) sichtbar
  • User (permanent): Root-Bilder + zugewiesene Unterordner
  • Client (30 Tage): Root-Bilder + zugewiesene Unterordner, Account laeuft nach 30 Tagen ab

Nextcloud-Integration

  • Nextcloud-Pfad: /volume1/nextcloud/data/Tom/files/Websitebilder
  • Mount im Container: /app/public/images/fulls:ro
  • Thumbnails-Volume: Docker-Volume thumbs (persistent)
  • Datenbank-Volume: Docker-Volume database (persistent, SQLite)
  • Workflow: Bild in Nextcloud hochladen -> max. 60s warten -> Seite neu laden -> fertig

Login-System & Nutzerverwaltung

Architektur

  • Backend: Node.js/Express auf Port 8090
  • Auth: JWT-Token als httpOnly Cookie (7 Tage gueltig)
  • Datenbank: SQLite unter /app/data/database.sqlite
  • Passwort-Hashing: bcryptjs (10 Rounds)

Rollen

Rolle Beschreibung Ablauf
admin Voller Zugriff, Nutzerverwaltung, alle Bilder Nie
user Root-Bilder + zugewiesene Ordner Nie
client Root-Bilder + zugewiesene Ordner 30 Tage nach Erstellung

Ordner-basierte Bildzuweisung

  • Bilder direkt in Websitebilder/ = oeffentlich (fuer alle sichtbar)
  • Bilder in Unterordnern (z.B. Websitebilder/Hochzeit/) = nur fuer zugewiesene Nutzer
  • Zuweisung erfolgt auf Ordner-Ebene (nicht einzelne Bilder)
  • Tabelle user_folders speichert Zuweisungen (user_id, folder_name)

Initialer Admin

  • Es wird kein festes Standardkonto mehr angelegt.
  • Bestehende Installationen behalten Nutzer und Rollen im persistenten SQLite-Volume.
  • Fuer frische Installationen kann einmalig INITIAL_ADMIN_USERNAME=MrDiderot zusammen mit INITIAL_ADMIN_PASSWORD_HASH gesetzt werden.

API-Endpunkte

Endpunkt Methode Beschreibung
/api/auth/login POST Login (username, password)
/api/auth/logout POST Logout (Cookie loeschen)
/api/auth/me GET Aktueller User
/api/auth/change-password POST Eigenes Passwort aendern
/api/admin/users GET/POST Nutzer auflisten / erstellen (mit Rolle)
/api/admin/users/:id DELETE Nutzer loeschen (nicht sich selbst)
/api/admin/users/:id/password PUT Admin aendert User-Passwort
/api/admin/folders GET Verfuegbare Unterordner auflisten
/api/admin/assign GET/POST Ordner-Zuweisungen anzeigen / setzen
/images/fulls/ GET Bilderliste (gefiltert nach User-Rolle + Ordnern)

Wichtige Konfiguration (_config.yml)

  • baseurl: URL der Website
  • title, subtitle, author: Seitentitel und Autor
  • header.title/subtitle: Header-Anzeige
  • footer.name/bio: Footer-Infos
  • social_urls: Links zu Social Media
  • exif: Welche EXIF-Tags angezeigt werden (Model, FNumber, ExposureTime, ISO)

Build-Befehle

Befehl Aktion
bundle install Ruby Dependencies installieren
bundle exec jekyll serve Lokaler Dev-Server (nur Frontend)
npm install Node Dependencies installieren
gulp build SCSS kompilieren + JS minifizieren
gulp resize Bilder zu fulls (1024px) + thumbs (512px)
gulp Alles (build + resize)

Docker / NAS Hosting

  • NAS: UGREEN mit UGOS PRO
  • Port: 8090 (intern und extern)
  • Domain: tom.mischlabs.de (via Cloudflare Tunnel)

Docker-Dateien

  • Dockerfile - Multi-Stage: Ruby/Jekyll baut Site -> Node.js Express serviert alles
  • docker-compose.yml - Photography Container + Watchtower, Volumes fuer Bilder/Thumbs/DB
  • entrypoint.sh - Thumbnail-Generierung + Node.js Server-Start
  • .dockerignore - Haelt Build-Context klein (kein .git, node_modules etc.)

Docker-Befehle (auf NAS via SSH)

Befehl Aktion
sudo docker compose up -d Container starten
sudo docker compose down Container stoppen
sudo docker compose logs -f photography Logs anzeigen
sudo docker compose pull && sudo docker compose up -d Manuelles Update

Deployment-Workflow (automatisch!)

  1. Aenderungen lokal machen (Code, Design)
  2. gulp build ausfuehren (JS + CSS minifizieren)
  3. Git commit & push nach master
  4. Gitea Actions baut automatisch Docker Image -> lokales Gitea Container Registry
  5. Watchtower auf NAS erkennt neues Image (alle 5 Min)
  6. Watchtower aktualisiert Container automatisch
  7. Fertig - Website aktualisiert ohne SSH!

Anpassungs-Roadmap

  • Titel, Subtitle, Autor anpassen (Mischkomposition / Tom Misch)
  • Social Media Links aktualisieren (Instagram: @Mischkomposition)
  • Sponsor-Bereich entfernen
  • Kontaktformular auf tom@mischlabs.de konfiguriert (Formsubmit.co)
  • Google Analytics vom Originalautor entfernt
  • Custom Domain: tom.mischlabs.de eingetragen
  • Nextcloud-Integration (Bilder aus Websitebilder-Ordner)
  • Dynamische Galerie (JS statt Jekyll-Loop)
  • Automatische Thumbnail-Generierung
  • Login-System mit JWT + SQLite
  • Admin-Dashboard (Nutzerverwaltung, Bildzuweisung)
  • Kunden-Portal (zugewiesene Bilder + Download)
  • Watchtower fuer automatische Updates
  • 3-Rollen-System (admin/user/client mit 30-Tage-Ablauf)
  • Ordner-basierte Bildzuweisung (Unterordner = private Kundenbilder)
  • Passwort-Aenderung (Self-Service + Admin kann fuer andere aendern)
  • Footer Bio-Text schreiben (optional)
  • Farbschema/Design anpassen
  • Eigene Kategorien/Alben erstellen (Feature-Erweiterung)
  • Admin-Passwort aendern!

Letzte Aktualisierung: 2026-04-12