feat: Sicherung, Anmeldebremse, Vorschaubilder -- und Schritt 5
SICHERUNG (tools/sichern.ps1, taeglich 04:30 als geplante Aufgabe). Die Datenbank wird nicht kopiert, sondern ueber SQLites eigene Sicherungsschnittstelle herausgeholt (server/src/backup.ts): im WAL-Modus liegt das Zuletzte noch nicht in media.db, und selbst alle drei Dateien zu kopieren ist nicht sicher, wenn waehrenddessen geschrieben wird. Die Bilder kommen aus einem NUR LESEND eingehaengten Volume dazu. Und sie prueft sich selbst: auspacken, Datenbank oeffnen, Medien/Token/ Benutzer zaehlen, mit dem laufenden Dienst vergleichen, sonst Fehler. Einmal wirklich zurueckgespielt -- leeres Volume, zweiter Dienst, Anmeldung mit dem echten Passwort, Bild abgerufen, Byte fuer Byte identisch. Eine Sicherung, die nie zurueckgespielt wurde, ist eine Hoffnung. ANMELDEBREMSE. Das Formular steht oeffentlich, und scrypt macht einen Versuch teuer -- aber teuer ist nicht selten. Fuenf freie Versuche je Adresse, dann Sperre ab 30 s mit Verdopplung bis 15 min, 429 samt Retry-After und einem Text, der sagt wie lange. Erfolg setzt zurueck. Nur im Speicher: wer sich aussperrt, startet den Container neu. Durchgemessen bis zur Erholung. VORSCHAUBILDER. sharp erzeugt beim Upload eine 320er WebP-Fassung unter /data/thumbs, ausgeliefert unter /t/<pfad>. Gemessen: 131502 -> 13078 Bytes, Faktor 10; eine Galerieseite faellt von 7,5 MB auf 766 KB. KEINE Spalte in der Datenbank -- ob es eine Vorschau gibt, sagt das Dateisystem, und die Galerie faellt bei 404 aufs Vollbild zurueck. Eine zweite Wahrheit, die auseinander- laufen kann, gibt es damit gar nicht erst. Ein Knopf zieht Fehlendes nach und nennt Zahlen statt "fertig". SCHRITT 5. Die Fivemanage-Dateien liegen in legacy/ mit Erklaerung; unsere docker-compose.media.yml heisst jetzt docker-compose.yml. Drei Volumes und drei Abbilder geloescht, rund 670 MB -- nachgezaehlt war vorher, dass kein Bild darin lag. Nebenbefund: `npm i sharp` scheitert auf diesem Rechner nicht an sharp, sondern an better-sqlite3 -- der Host laeuft auf Node 24 (ABI 137), node-gyp uebernimmt und findet keine Bauwerkzeuge. Genau die Falle aus dem Dockerfile. Eingetragen wurde mit --package-lock-only, gebaut wird im Abbild auf Node 22. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
@@ -0,0 +1,14 @@
|
||||
# Der Fivemanage-Anlauf
|
||||
|
||||
Was hier liegt, hat den Lite-Stack betrieben: PostgreSQL, MinIO, ClickHouse,
|
||||
Dashboard. Der Stack lief; woran er gescheitert ist, steht in der ROADMAP
|
||||
unter "Warum nicht Fivemanage Lite" — kurz: eine Oberflaeche, in der jeder
|
||||
Fehlschlag lautlos verschluckt wird.
|
||||
|
||||
**Die Container sind am 11.08.2026 geloescht worden**, dazu die drei Volumes
|
||||
(nachgezaehlt: kein einziges Bild darin) und die Abbilder. Diese Dateien
|
||||
bleiben als Beleg und weil in ihren Kommentaren Dinge stehen, die uns wieder
|
||||
begegnen — Portainer nimmt unter "Compose path" genau EINE Datei, Host-Ports
|
||||
gehoeren an 0.0.0.0 und nicht an 127.0.0.1.
|
||||
|
||||
Nichts hiervon wird noch gestartet.
|
||||
@@ -0,0 +1,85 @@
|
||||
# Zum Ausprobieren auf Docker Desktop.
|
||||
#
|
||||
# Der Unterschied zur Betriebsfassung ist Absicht und in beide Richtungen:
|
||||
# hier sind die Ports offen und es gibt keinen Reverse Proxy, dort ist es
|
||||
# umgekehrt. Eine `beta.23` gehoert erst auf einen Rechner, an dem nichts
|
||||
# haengt — und wenn sie dort traegt, auf den Server.
|
||||
#
|
||||
# docker compose -f docker-compose.local.yml up -d
|
||||
#
|
||||
# Danach: http://localhost:8080 (admin / ADMIN_PASSWORD aus .env)
|
||||
# http://localhost:9001 (MinIO, lite / MINIO_ROOT_PASSWORD)
|
||||
|
||||
services:
|
||||
db:
|
||||
image: postgres:16-alpine
|
||||
environment:
|
||||
POSTGRES_DB: fivemanage_lite
|
||||
POSTGRES_USER: lite
|
||||
POSTGRES_PASSWORD: ${DB_PASSWORD:?bitte setzen}
|
||||
volumes:
|
||||
- pgdata:/var/lib/postgresql/data
|
||||
healthcheck:
|
||||
test: ["CMD-SHELL", "pg_isready -U lite -d fivemanage_lite"]
|
||||
interval: 5s
|
||||
timeout: 5s
|
||||
retries: 20
|
||||
|
||||
minio:
|
||||
image: minio/minio:latest
|
||||
command: server /data --console-address ":9001"
|
||||
environment:
|
||||
MINIO_ROOT_USER: lite
|
||||
MINIO_ROOT_PASSWORD: ${MINIO_ROOT_PASSWORD:?bitte setzen}
|
||||
# Oertlich: die Dateien liegen unter derselben Adresse, unter der MinIO
|
||||
# antwortet. Erst auf dem Server tritt fivecdn.d4rkst3r.de an die Stelle.
|
||||
MINIO_SERVER_URL: http://localhost:9000
|
||||
ports:
|
||||
- "9000:9000"
|
||||
- "9001:9001"
|
||||
volumes:
|
||||
- minio:/data
|
||||
healthcheck:
|
||||
test: ["CMD", "mc", "ready", "local"]
|
||||
interval: 5s
|
||||
timeout: 5s
|
||||
retries: 20
|
||||
|
||||
lite:
|
||||
# ghcr.io, NICHT Docker Hub: dort steht die Reihe bei 0.1.0-beta.16
|
||||
# still, auf ghcr.io laeuft sie weiter. Die Test-Compose des Projekts
|
||||
# zeigt `fivemanage/lite:latest` — das ist Docker Hub und damit alt.
|
||||
image: ghcr.io/fivemanage/lite:0.1.0-beta.23
|
||||
depends_on:
|
||||
db:
|
||||
condition: service_healthy
|
||||
minio:
|
||||
condition: service_healthy
|
||||
environment:
|
||||
PORT: "8080"
|
||||
ENV: dev
|
||||
DSN: postgres://lite:${DB_PASSWORD:?bitte setzen}@db:5432/fivemanage_lite?sslmode=disable
|
||||
ADMIN_PASSWORD: ${ADMIN_PASSWORD:?bitte setzen}
|
||||
API_TOKEN_HMAC_SECRET: ${API_TOKEN_HMAC_SECRET:?bitte setzen}
|
||||
S3_PROVIDER: minio
|
||||
AWS_ENDPOINT: http://minio:9000
|
||||
AWS_ACCESS_KEY_ID: lite
|
||||
AWS_SECRET_ACCESS_KEY: ${MINIO_ROOT_PASSWORD:?bitte setzen}
|
||||
AWS_BUCKET: media
|
||||
# Aus der Vorlage des Projekts uebernommen; fuer MinIO ist die Region
|
||||
# gleichgueltig, das SDK verlangt aber eine.
|
||||
AWS_REGION: eu-west-1
|
||||
|
||||
# Woraus die OEFFENTLICHE Adresse gebaut wird, die Lite nach dem Upload
|
||||
# zurueckgibt. Steht nicht im README, nur in deren .env.template — und
|
||||
# ohne sie kaemen Adressen zurueck, die nur innerhalb von Docker gelten.
|
||||
#
|
||||
# Endpunkt plus Bucket, wie in der Vorlage
|
||||
# (BUCKET_DOMAIN=http://localhost:9000/lite-dev).
|
||||
BUCKET_DOMAIN: http://localhost:9000/media
|
||||
ports:
|
||||
- "8080:8080"
|
||||
|
||||
volumes:
|
||||
pgdata:
|
||||
minio:
|
||||
@@ -0,0 +1,37 @@
|
||||
# Ergaenzung fuer einen Reverse Proxy, der IM SELBEN Docker-Netz haengt.
|
||||
#
|
||||
# Der sauberere der beiden Wege: kein Port muss auf dem Host offen sein, der
|
||||
# Proxy spricht die Container direkt an.
|
||||
#
|
||||
# docker compose -f docker-compose.yml -f docker-compose.proxynet.yml up -d
|
||||
#
|
||||
# NICHT ueber Portainer aus dem Repo: dort nimmt "Compose path" nur EINE
|
||||
# Datei, und eine Ergaenzung wird stillschweigend ignoriert. Wer diesen Weg
|
||||
# will, fuehrt die beiden Dateien zusammen oder startet von Hand.
|
||||
#
|
||||
# VORAUSSETZUNG: das Netz muss es schon geben, und der Proxy muss darin
|
||||
# haengen. Nachsehen:
|
||||
#
|
||||
# docker network ls
|
||||
# docker network inspect <name> zeigt die Mitglieder
|
||||
#
|
||||
# Haengt der Proxy nirgends mit drin, ist das hier der falsche Weg — dann
|
||||
# bleibt es bei den Host-Ports aus docker-compose.yml, die dann auch offen
|
||||
# bleiben duerfen. Ein Netz anzulegen, in dem nur diese Container sitzen,
|
||||
# bringt nichts: der Proxy muesste mit hinein.
|
||||
#
|
||||
# Danach in NPM:
|
||||
# fivecdn.d4rkst3r.de -> http://minio:9000
|
||||
# <oberflaeche> -> http://lite:8080
|
||||
|
||||
services:
|
||||
minio:
|
||||
networks: [internal, proxy]
|
||||
|
||||
lite:
|
||||
networks: [internal, proxy]
|
||||
|
||||
networks:
|
||||
proxy:
|
||||
name: ${PROXY_NETWORK:-proxy}
|
||||
external: true
|
||||
@@ -0,0 +1,130 @@
|
||||
# Fivemanage Lite — fuer den Betrieb, ueber Portainer aus diesem Repo.
|
||||
#
|
||||
# Abgeleitet aus den beiden Compose-Dateien im Projekt (fivemanage/lite) und
|
||||
# dem README. Deren docker-compose.yml ist fuer die ENTWICKLUNG: sie startet
|
||||
# Datenbank, ClickHouse, MinIO und Jaeger, aber nicht die Anwendung, und mit
|
||||
# Standardpasswoertern. Die docker-compose.test.yml zeigt dafuer, wie der
|
||||
# App-Container verdrahtet wird — und dass MySQL genuegt.
|
||||
#
|
||||
# Bewusst NICHT dabei:
|
||||
#
|
||||
# ClickHouse und Jaeger. Beides ist strukturiertes Logging und Tracing. Fuer
|
||||
# das Ablegen von Bildern braucht es sie nicht, und ClickHouse ist eine
|
||||
# schwere Abhaengigkeit. Nachruesten geht spaeter.
|
||||
#
|
||||
# Der Weg nach aussen steht HIER DRIN und nicht in einer Ergaenzungsdatei.
|
||||
# Zuerst war er ausgelagert, weil sich je Aufbau unterscheidet, wie ein
|
||||
# Reverse Proxy seine Ziele findet. In Portainer nimmt "Compose path" aber
|
||||
# EINE Datei — die Ergaenzung wurde stillschweigend nicht angewandt, und das
|
||||
# Ergebnis war ein Stack, in dem jeder Container gesund meldet und trotzdem
|
||||
# alles 502 liefert. Eine Trennung, die man nicht anwenden kann, ist keine.
|
||||
#
|
||||
# Wer den Proxy im selben Docker-Netz hat, nimmt docker-compose.proxynet.yml
|
||||
# dazu — das ist der sauberere Weg, aber nicht der hier gegangene.
|
||||
|
||||
services:
|
||||
db:
|
||||
image: postgres:16-alpine
|
||||
restart: unless-stopped
|
||||
environment:
|
||||
POSTGRES_DB: fivemanage_lite
|
||||
POSTGRES_USER: lite
|
||||
POSTGRES_PASSWORD: ${DB_PASSWORD:?bitte in .env oder als Stack-Variable setzen}
|
||||
volumes:
|
||||
- pgdata:/var/lib/postgresql/data
|
||||
networks: [internal]
|
||||
healthcheck:
|
||||
# Ohne das startet die App gegen eine Datenbank, die noch nicht
|
||||
# antwortet, und beendet sich — beim ersten Hochfahren jedes Mal.
|
||||
test: ["CMD-SHELL", "pg_isready -U lite -d fivemanage_lite"]
|
||||
interval: 10s
|
||||
timeout: 5s
|
||||
retries: 12
|
||||
|
||||
minio:
|
||||
image: minio/minio:latest
|
||||
restart: unless-stopped
|
||||
command: server /data --console-address ":9001"
|
||||
environment:
|
||||
MINIO_ROOT_USER: lite
|
||||
MINIO_ROOT_PASSWORD: ${MINIO_ROOT_PASSWORD:?bitte setzen}
|
||||
MINIO_SERVER_URL: ${PUBLIC_URL:?bitte setzen}
|
||||
volumes:
|
||||
- minio:/data
|
||||
networks: [internal]
|
||||
ports:
|
||||
# Die Dateien, fuer den Reverse Proxy ueber den Host:
|
||||
# fivecdn.d4rkst3r.de -> http://host.docker.internal:9100
|
||||
#
|
||||
# 9100 statt 9000, weil 9000 auf diesem Server an Portainer geht. Im
|
||||
# Container bleibt es 9000; nur die Seite zum Host wandert.
|
||||
#
|
||||
# An alle Adressen gebunden, und das ist kein Versehen: der Nginx Proxy
|
||||
# Manager liegt im Standard-Bridge-Netz und kommt ueber die Docker-
|
||||
# Bruecke herein, nicht ueber Loopback — ein an 127.0.0.1 gebundener
|
||||
# Port nimmt diese Anfrage nicht an. Genauso laufen hier schon d4rkbot
|
||||
# (3080) und cdn-files (8090).
|
||||
#
|
||||
# ZU IST DER PORT DURCH DIE FIREWALL, nicht durch die Bindung. 9100 und
|
||||
# 9101 gehoeren von aussen dicht; oeffentlich soll nur NPM auf 80/443
|
||||
# sein. ss -tlnp | grep -E '9100|9101'
|
||||
- "${BIND_ADDR:-0.0.0.0}:${MINIO_HOST_PORT:-9100}:9000"
|
||||
healthcheck:
|
||||
test: ["CMD", "mc", "ready", "local"]
|
||||
interval: 10s
|
||||
timeout: 5s
|
||||
retries: 12
|
||||
|
||||
lite:
|
||||
# ghcr.io, NICHT Docker Hub: dort steht die Reihe bei 0.1.0-beta.16
|
||||
# still, auf ghcr.io laeuft sie weiter. Die Test-Compose des Projekts
|
||||
# zeigt `fivemanage/lite:latest` — das ist Docker Hub und damit alt.
|
||||
image: ghcr.io/fivemanage/lite:0.1.0-beta.23
|
||||
restart: unless-stopped
|
||||
depends_on:
|
||||
db:
|
||||
condition: service_healthy
|
||||
minio:
|
||||
condition: service_healthy
|
||||
environment:
|
||||
PORT: "8080"
|
||||
ENV: production
|
||||
# PostgreSQL, und zwar zwingend: beta.23 geht direkt in den
|
||||
# pgdriver — DB_DRIVER wird nicht ausgewertet. Eine MySQL-DSN endet in
|
||||
# "pgdriver: invalid scheme: lite", weil der Treiber sie als URI liest.
|
||||
#
|
||||
# Die docker-compose.test.yml des Projekts zeigt MySQL, benutzt dafuer
|
||||
# aber fivemanage/lite:latest von Docker Hub — und die Reihe steht dort
|
||||
# bei beta.16 still. Das README hat recht, die Testdatei ist alt.
|
||||
DSN: postgres://lite:${DB_PASSWORD:?bitte setzen}@db:5432/fivemanage_lite?sslmode=disable
|
||||
ADMIN_PASSWORD: ${ADMIN_PASSWORD:?bitte setzen}
|
||||
API_TOKEN_HMAC_SECRET: ${API_TOKEN_HMAC_SECRET:?bitte setzen}
|
||||
S3_PROVIDER: minio
|
||||
AWS_ENDPOINT: http://minio:9000
|
||||
AWS_ACCESS_KEY_ID: lite
|
||||
AWS_SECRET_ACCESS_KEY: ${MINIO_ROOT_PASSWORD:?bitte setzen}
|
||||
AWS_BUCKET: media
|
||||
# Aus der Vorlage des Projekts uebernommen; fuer MinIO ist die Region
|
||||
# gleichgueltig, das SDK verlangt aber eine.
|
||||
AWS_REGION: eu-west-1
|
||||
|
||||
# Woraus die OEFFENTLICHE Adresse gebaut wird, die Lite nach dem Upload
|
||||
# zurueckgibt. Steht nicht im README, nur in deren .env.template — und
|
||||
# ohne sie kaemen Adressen zurueck, die nur innerhalb von Docker gelten.
|
||||
#
|
||||
# Endpunkt plus Bucket, wie in der Vorlage
|
||||
# (BUCKET_DOMAIN=http://localhost:9000/lite-dev).
|
||||
BUCKET_DOMAIN: ${PUBLIC_URL:?bitte setzen}/media
|
||||
ports:
|
||||
# Die Oberflaeche: fivemanage.d4rkst3r.de -> http://host.docker.internal:9101
|
||||
# 9101 statt 8080, weil 8080 an nextcloud-aio geht. Siehe minio oben.
|
||||
- "${BIND_ADDR:-0.0.0.0}:${LITE_HOST_PORT:-9101}:8080"
|
||||
networks: [internal]
|
||||
|
||||
networks:
|
||||
internal:
|
||||
driver: bridge
|
||||
|
||||
volumes:
|
||||
pgdata:
|
||||
minio:
|
||||
Reference in New Issue
Block a user