docs(env): Beispieldateien kürzen, Erklärungen ins README
Die beiden .env.example zusammen waren 251 Zeilen für 40 Schlüssel – gut gemeint, aber niemand liest einen Absatz pro Variable. Jetzt eine Zeile je Schlüssel (58 + 89), die Begründungen stehen im README unter 'Einstellungen', gebündelt als die sieben Dinge, die nicht beim Start auffallen, sondern später. Dabei durch einen echten Start aus den Beispieldateien gefunden: STORAGE_PATH fehlte, Vorgabe ./data wird im Container zu /app/data, und der Start endete in 'mkdir /app/data: permission denied'. Das Abbild setzt STORAGE_PATH und TMP_PATH jetzt selbst – es kennt seine Verzeichnisse besser als eine Beispieldatei. Eine .env darf weiter überschreiben. Geprüft: jeder Schlüssel, den die Anwendung liest, steht weiterhin in deploy/.env.example; eine frische Instanz startet allein aus den beiden Beispieldateien. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
1 parent
35ebf609b7
commit
428fd2672c
5 files changed
+195
-186
No files matched your search
+20
-53
@@ -1,91 +1,58 @@
|
||||
# Aether – das Nötigste für eine neue Umgebung.
|
||||
#
|
||||
# cp .env.example .env
|
||||
#
|
||||
# Vollständige Liste aller Schalter (OIDC, OCR, Thumbnails, Kontingente …):
|
||||
# deploy/.env.example
|
||||
# Aether – das Nötigste für eine neue Umgebung. cp .env.example .env
|
||||
# Erklärungen: README.md, Abschnitt „Einstellungen"
|
||||
# Alle Schalter: deploy/.env.example
|
||||
|
||||
# ── Pflicht ───────────────────────────────────────────────────────────────────
|
||||
|
||||
# Steuert nur die Form der Logausgabe: `development` schreibt sie farbig und
|
||||
# mehrzeilig, `production` als JSON für deinen Logsammler.
|
||||
APP_ENV=production
|
||||
|
||||
|
||||
# Wie die Cloud von außen erreichbar ist. Wird für OIDC-Rücksprünge,
|
||||
# WOPI-Rückrufe und Freigabe-Links benutzt – ein falscher Wert fällt erst
|
||||
# dort auf, nicht beim Start.
|
||||
# Adresse, unter der der Browser die Cloud sieht. Ohne Schrägstrich am Ende.
|
||||
PUBLIC_URL=https://cloud.example.com
|
||||
|
||||
# openssl rand -hex 32
|
||||
SESSION_SECRET=
|
||||
|
||||
# `postgres` ist der Dienstname aus dem Compose, nicht localhost – aus dem
|
||||
# Container heraus ist localhost er selbst. Ohne diese Zeile greift die
|
||||
# Voreinstellung `localhost`, und der Start endet in „migrations failed".
|
||||
# DB_HOST ist der Dienstname aus dem Compose, nicht localhost.
|
||||
DB_HOST=postgres
|
||||
DB_PORT=5432
|
||||
DB_NAME=aether
|
||||
DB_USER=aether
|
||||
# Jedes Zeichen ist erlaubt, auch % @ : / und Leerzeichen.
|
||||
# Jedes Zeichen erlaubt, auch % @ : / und Leerzeichen.
|
||||
DB_PASSWORD=
|
||||
|
||||
# Wohin die Dateien auf dem Wirt kommen. Ein gewöhnliches Verzeichnis, kein
|
||||
# Docker-Volume – so kommst du per SFTP oder Dateimanager daran.
|
||||
# Verzeichnis auf dem Wirt. Nur lesend anfassen – zum Hineinlegen: WebDAV.
|
||||
DATA_PATH=/pfad/zu/aether-data
|
||||
|
||||
# `id -u` und `id -g`. Ohne das gehören die Dateien einem Container-Nutzer.
|
||||
# `id -u` / `id -g` – sonst gehören die Dateien einem Container-Nutzer.
|
||||
APP_UID=1000
|
||||
APP_GID=1000
|
||||
|
||||
# ── Reverse Proxy ─────────────────────────────────────────────────────────────
|
||||
|
||||
# X-Forwarded-For/-Proto werden NUR von diesen Adressen geglaubt. Steht hier
|
||||
# das Falsche, sieht die Anwendung überall die IP des Proxys – Rate-Limit und
|
||||
# Audit-Log werden damit wertlos.
|
||||
# Nur diesen Adressen wird X-Forwarded-For/-Proto geglaubt.
|
||||
TRUSTED_PROXIES=172.18.0.1
|
||||
|
||||
# Port auf dem Wirt, gebunden auf loopback. Im Container bleibt es 8080.
|
||||
# Port auf dem Wirt, auf loopback gebunden. Im Container bleibt es 8080.
|
||||
APP_PORT=8080
|
||||
|
||||
# ── Erster Start ──────────────────────────────────────────────────────────────
|
||||
|
||||
# Legt beim allerersten Start den Admin an. Danach hier leeren – das Konto
|
||||
# bleibt, das Passwort steht sonst dauerhaft in der Datei.
|
||||
# Legt den Admin an. Danach ADMIN_PASSWORD leeren.
|
||||
ADMIN_USERNAME=admin
|
||||
ADMIN_PASSWORD=
|
||||
|
||||
# ── Anmeldung über einen Identitätsanbieter (optional) ───────────────────────
|
||||
# Leerer OIDC_ISSUER = aus, dann nur Benutzername + Passwort.
|
||||
# Die Rücksprung-Adresse muss exakt <PUBLIC_URL>/api/v1/auth/oidc/callback sein
|
||||
# und beim Anbieter als erlaubte Redirect-URI eingetragen werden.
|
||||
# Leerer OIDC_ISSUER = aus.
|
||||
OIDC_ISSUER=
|
||||
OIDC_CLIENT_ID=aether
|
||||
OIDC_CLIENT_SECRET=
|
||||
# Muss exakt <PUBLIC_URL>/api/v1/auth/oidc/callback sein.
|
||||
OIDC_REDIRECT_URL=https://cloud.example.com/api/v1/auth/oidc/callback
|
||||
|
||||
# Bestehendes Konto mit derselben Kennung verbinden, statt ein zweites
|
||||
# anzulegen. **Vor der ersten Anmeldung setzen** – danach existiert das zweite
|
||||
# Konto ("marc2", leer, ohne Adminrecht) schon, und das Verbinden kommt zu spät.
|
||||
#
|
||||
# Nur bei einem eigenen Anbieter (PocketID, Authentik), dessen Konten du selbst
|
||||
# anlegst. Bei freier Registrierung wäre es die Übernahme fremder Konten.
|
||||
# Bestehendes Konto verbinden statt ein zweites anzulegen.
|
||||
# VOR der ersten Anmeldung setzen – danach ist es zu spät.
|
||||
OIDC_LINK_BY_USERNAME=false
|
||||
|
||||
# ── Office (optional) ─────────────────────────────────────────────────────────
|
||||
# Leer lassen = aus. Den passenden Container-Schnipsel (Collabora, OnlyOffice
|
||||
# oder Euro-Office) findest du im README – er bringt seine eigenen Variablen
|
||||
# mit. Hier steht nur, was Aether selbst wissen muss.
|
||||
#
|
||||
# Drei Adressen für drei Richtungen, und sie sind selten gleich:
|
||||
# OFFICE_URL Backend → Office-Server
|
||||
# OFFICE_PUBLIC_URL Browser → Office-Server
|
||||
# OFFICE_WOPI_URL Office-Server → Aether (NICHT localhost – aus seinem
|
||||
# Container heraus ist das er selbst)
|
||||
# Leer = aus. Container-Schnipsel: README.md
|
||||
OFFICE_PROVIDER=
|
||||
# Backend → Office
|
||||
OFFICE_URL=http://office:9980
|
||||
# Browser → Office
|
||||
OFFICE_PUBLIC_URL=https://office.example.com
|
||||
# Office → Aether. NICHT localhost, NICHT der veröffentlichte Port.
|
||||
OFFICE_WOPI_URL=http://app:8080
|
||||
|
||||
# Ziele, die das Backend anfragen darf – gegen SSRF. Nur der Office-Server.
|
||||
# Gegen SSRF: was das Backend anfragen darf.
|
||||
OFFICE_ALLOWED_HOSTS=office
|
||||
@@ -119,6 +119,80 @@ Direkt (ohne Proxy): http://localhost:8080/health
|
||||
|
||||
---
|
||||
|
||||
## Einstellungen
|
||||
|
||||
Zwei Beispieldateien, je nach Zweck:
|
||||
|
||||
| | |
|
||||
|---|---|
|
||||
| `.env.example` (Wurzel) | das Nötigste zum Betreiben |
|
||||
| `deploy/.env.example` | alle Schalter, auch die optionalen |
|
||||
|
||||
Beide sind knapp gehalten – was dahintersteckt, steht hier.
|
||||
|
||||
### Was schiefgeht, wenn man es falsch setzt
|
||||
|
||||
Diese sieben fallen **nicht** beim Start auf, sondern später und an
|
||||
unerwarteter Stelle. Der Rest hat brauchbare Vorgaben.
|
||||
|
||||
**`DB_HOST=postgres`** – nicht `localhost`. Aus dem Container heraus ist
|
||||
`localhost` er selbst; die Voreinstellung führt zu `migrations failed` beim
|
||||
Start.
|
||||
|
||||
**`DB_PASSWORD`** darf jedes Zeichen enthalten, auch `% @ : /` und
|
||||
Leerzeichen. Es gibt keine Liste erlaubter Zeichen – wer die erst nachschlagen
|
||||
muss, wählt am Ende ein schwächeres Passwort.
|
||||
|
||||
**`PUBLIC_URL`** ist die Adresse, unter der der **Browser** die Cloud sieht,
|
||||
ohne Schrägstrich am Ende. Ein falscher Wert startet klaglos und fällt erst
|
||||
auf, wenn ein Freigabe-Link oder ein OIDC-Rücksprung ins Leere zeigt.
|
||||
|
||||
**`TRUSTED_PROXIES`** entscheidet, wem `X-Forwarded-For` geglaubt wird. Steht
|
||||
hier das Falsche, sieht die Anwendung überall die IP des Proxys – Rate-Limit
|
||||
und Audit-Log werden damit wertlos, ohne dass irgendetwas nach Fehler aussieht.
|
||||
|
||||
**`ADMIN_PASSWORD`** legt beim allerersten Start den Admin an. Danach leeren:
|
||||
Das Konto bleibt, das Passwort stünde sonst dauerhaft in einer Datei.
|
||||
|
||||
**`OIDC_LINK_BY_USERNAME`** verbindet ein bestehendes Konto mit derselben
|
||||
Kennung, statt ein zweites anzulegen. **Vor der ersten Anmeldung setzen** –
|
||||
danach existiert das zweite Konto (`marc2`, leer, ohne Adminrecht) schon, und
|
||||
das Verbinden kommt zu spät. Nur bei einem Anbieter sinnvoll, dessen Konten du
|
||||
selbst anlegst (PocketID, Authentik); bei freier Registrierung wäre es die
|
||||
Übernahme fremder Konten. Verbunden wird ohnehin nur, was noch keine Bindung
|
||||
hat.
|
||||
|
||||
**`DATA_PATH`** ist ein gewöhnliches Verzeichnis auf dem Wirt, kein
|
||||
Docker-Volume – deshalb kommst du per SFTP, rsync oder im Dateimanager daran.
|
||||
Nur lesend anfassen: Wer von Hand hineinschreibt, hat eine Datei, die die
|
||||
Datenbank nicht kennt; die Cloud sieht sie nicht, und der GC räumt sie
|
||||
irgendwann weg. Zum Hineinlegen ist WebDAV der Weg. Dazu `APP_UID`/`APP_GID`
|
||||
aus `id -u` und `id -g`, sonst gehören die Dateien einem Container-Nutzer.
|
||||
|
||||
### Volltextsuche (OCR)
|
||||
|
||||
Standardmäßig an. Fehlen `ocrmypdf`/`tesseract` im Abbild, schaltet sich der
|
||||
Arbeiter beim Start selbst ab und die Cloud läuft ohne Volltext weiter.
|
||||
|
||||
`OCR_MAX_PAGES=50` ist eine Bremse, keine Schikane: Erkennung kostet rund eine
|
||||
Minute je gescannter Seite, und ohne Grenze blockiert ein dickes Handbuch die
|
||||
Warteschlange für alles andere. `OCR_LANGUAGES` kennt `deu` und `eng`; weitere
|
||||
brauchen ein zusätzliches `apk`-Paket im Dockerfile.
|
||||
|
||||
### Office
|
||||
|
||||
Die drei Adressen und ihre Fallstricke stehen weiter unten bei
|
||||
[Office](#office-collabora--onlyoffice--euro-office) – dort, wo auch die
|
||||
Container-Schnipsel liegen.
|
||||
|
||||
### WebDAV
|
||||
|
||||
Läuft unter `/dav/`, kein Schalter nötig. Dein Reverse Proxy muss
|
||||
`PROPFIND`, `MKCOL`, `MOVE` und `COPY` durchreichen – viele Vorlagen erlauben
|
||||
nur `GET`/`POST`, und dann scheitert das Einbinden mit einem `405`.
|
||||
|
||||
---
|
||||
|
||||
## Abbild bauen und veröffentlichen
|
||||
|
||||
```bash
|
||||
|
||||
+29
@@ -646,6 +646,35 @@ breiteste.
|
||||
|
||||
---
|
||||
|
||||
## Frische Umgebung nur aus den Beispieldateien (24.08.2026)
|
||||
|
||||
Der einzige Test, der zählt: `docker-compose.example.yml` + `.env.example`
|
||||
kopieren, Passwörter eintragen, starten. Nichts sonst.
|
||||
|
||||
Beim ersten Durchlauf brachte er sofort einen Fehler ans Licht, den keine
|
||||
Codeprüfung findet:
|
||||
|
||||
```
|
||||
migrations up to date
|
||||
FTL blob storage init failed error="mkdir /app/data: permission denied"
|
||||
```
|
||||
|
||||
`STORAGE_PATH` hat die Voreinstellung `./data` – richtig für ein Binary, das
|
||||
man von Hand startet, falsch im Container, wo daraus `/app/data` wird statt
|
||||
des Mounts unter `/data`. Die schlanke `.env.example` führte den Schlüssel
|
||||
nicht, weil er „eine brauchbare Vorgabe" hat. Hatte er nicht.
|
||||
|
||||
Jetzt setzt das **Abbild** `STORAGE_PATH` und `TMP_PATH` selbst. Es kennt seine
|
||||
Verzeichnisstruktur besser als jede Beispieldatei; eine `.env` darf weiterhin
|
||||
überschreiben.
|
||||
|
||||
- [ ] Frische Umgebung nur aus den beiden Beispieldateien → `migrations up to
|
||||
date`, `admin account ready`, `listening` 🔎
|
||||
- [ ] `/health` 200, Anmeldung 200, `data/tmp` liegt auf dem Wirt 🔎
|
||||
- [ ] Dabei ein Passwort mit `%` und `@` verwendet 🔎
|
||||
|
||||
---
|
||||
|
||||
## Datenbank-Passwort mit Sonderzeichen (24.08.2026)
|
||||
|
||||
Die Verbindungszeichenkette wurde mit `fmt.Sprintf` zusammengeklebt. Beim
|
||||
|
||||
+62
-133
@@ -1,160 +1,89 @@
|
||||
# Aether – Environment Variables
|
||||
# Copy to .env and fill in values. Never commit .env!
|
||||
# Aether – alle Schalter. cp deploy/.env.example deploy/.env
|
||||
# Erklärungen und Fallstricke: README.md, Abschnitt „Einstellungen"
|
||||
#
|
||||
# Für den reinen Betrieb genügt die kürzere .env.example im
|
||||
# Wurzelverzeichnis – hier steht zusätzlich alles Optionale.
|
||||
|
||||
# ── App ──────────────────────────────────────────────────────────────────────
|
||||
# ── App ───────────────────────────────────────────────────────────────────────
|
||||
APP_ENV=production # development | production
|
||||
|
||||
# Internal listen address. Your external reverse proxy forwards here.
|
||||
APP_LISTEN_ADDR=:8080
|
||||
|
||||
# Public-facing URL (used for OIDC redirects, WOPI callbacks, share links).
|
||||
# Must match what the browser sees — include scheme + domain, no trailing slash.
|
||||
APP_LISTEN_ADDR=:8080 # im Container; der Proxy leitet hierher
|
||||
PUBLIC_URL=https://cloud.example.com
|
||||
|
||||
# Comma-separated IPs or CIDRs of reverse proxies allowed to set
|
||||
# X-Forwarded-For / X-Forwarded-Proto. Everyone else is untrusted.
|
||||
# Example: 172.18.0.1,10.0.0.0/8
|
||||
# IPs/CIDRs der Proxys, denen X-Forwarded-For/-Proto geglaubt wird.
|
||||
TRUSTED_PROXIES=172.18.0.1
|
||||
|
||||
# ── Database ─────────────────────────────────────────────────────────────────
|
||||
# ── Datenbank ─────────────────────────────────────────────────────────────────
|
||||
# DB_HOST ist der Dienstname aus dem Compose, nicht localhost.
|
||||
DB_HOST=postgres
|
||||
DB_PORT=5432
|
||||
DB_NAME=aether
|
||||
DB_USER=aether
|
||||
# Jedes Zeichen erlaubt, auch % @ : / und Leerzeichen.
|
||||
DB_PASSWORD=changeme_strong_password
|
||||
|
||||
# ── Session ───────────────────────────────────────────────────────────────────
|
||||
# Generate with: openssl rand -hex 32
|
||||
SESSION_SECRET=changeme_generate_with_openssl_rand_hex_32
|
||||
SESSION_MAX_AGE=86400 # seconds (24h)
|
||||
# ── Sitzung ───────────────────────────────────────────────────────────────────
|
||||
SESSION_SECRET=changeme_generate_with_openssl_rand_hex_32 # openssl rand -hex 32
|
||||
SESSION_MAX_AGE=86400 # Sekunden
|
||||
|
||||
# ── Storage ───────────────────────────────────────────────────────────────────
|
||||
STORAGE_PATH=/data
|
||||
# ── Speicher ──────────────────────────────────────────────────────────────────
|
||||
STORAGE_PATH=/data # im Container
|
||||
TMP_PATH=/data/tmp
|
||||
# Verzeichnis auf dem Wirt. Nur lesend anfassen – zum Hineinlegen: WebDAV.
|
||||
DATA_PATH=/pfad/zu/aether-data
|
||||
# `id -u` / `id -g` – sonst gehören die Dateien einem Container-Nutzer.
|
||||
APP_UID=1000
|
||||
APP_GID=1000
|
||||
# Port auf dem Wirt, auf loopback gebunden.
|
||||
APP_PORT=8080
|
||||
|
||||
# ── Admin seed ────────────────────────────────────────────────────────────────
|
||||
# Used only on first startup to create the initial admin account.
|
||||
# Remove or leave blank after first start.
|
||||
# ── Erster Start ──────────────────────────────────────────────────────────────
|
||||
# Legt den Admin an. Danach ADMIN_PASSWORD leeren.
|
||||
ADMIN_USERNAME=admin
|
||||
ADMIN_PASSWORD=changeme_strong_admin_password
|
||||
|
||||
# ── OIDC (optional, Phase 4) ─────────────────────────────────────────────────
|
||||
# Wenn OIDC_ISSUER leer ist, ist OIDC-Login deaktiviert (kein SSO-Button).
|
||||
# OIDC_REDIRECT_URL muss exakt <PUBLIC_URL>/api/v1/auth/oidc/callback sein
|
||||
# und beim IdP als erlaubte Redirect-URI registriert werden.
|
||||
# ── OIDC (optional) ───────────────────────────────────────────────────────────
|
||||
# Leerer OIDC_ISSUER = aus. OIDC_REDIRECT_URL muss exakt
|
||||
# <PUBLIC_URL>/api/v1/auth/oidc/callback sein und beim Anbieter eingetragen.
|
||||
# OIDC_ISSUER=https://your-idp.example.com
|
||||
# OIDC_CLIENT_ID=aether
|
||||
# OIDC_CLIENT_SECRET=
|
||||
# OIDC_REDIRECT_URL=https://cloud.example.com/api/v1/auth/oidc/callback
|
||||
# Bestehendes Konto verbinden statt ein zweites anzulegen.
|
||||
# VOR der ersten Anmeldung setzen – danach ist es zu spät.
|
||||
# OIDC_LINK_BY_USERNAME=true
|
||||
|
||||
# ── WebDAV ────────────────────────────────────────────────────────────────────
|
||||
# Erreichbar unter /dav/ (Basic Auth, Username + Passwort). Kein Setting nötig.
|
||||
# Reverse Proxy muss PROPFIND/MKCOL/MOVE/COPY durchreichen.
|
||||
# ── Volltextsuche (OCR) ───────────────────────────────────────────────────────
|
||||
# Standardmäßig an; fehlen ocrmypdf/tesseract, schaltet es sich selbst ab.
|
||||
# OCR_ENABLED=false
|
||||
# OCR_LANGUAGES=deu+eng # weitere brauchen ein apk-Paket im Dockerfile
|
||||
# OCR_MAX_PAGES=50 # 0 = unbegrenzt; rund 1 Minute je Seite
|
||||
# OCR_TIMEOUT=10m # Notbremse je Datei
|
||||
|
||||
# ── Office / WOPI ─────────────────────────────────────────────────────────────
|
||||
# Steht weiter unten, mit allen Adressen. (Hier stand bis zum 24.08.2026 ein
|
||||
# Rest aus der Planung mit OFFICE_SERVER_URL – den Schlüssel gibt es nicht.)
|
||||
# ── App-Umschalter ────────────────────────────────────────────────────────────
|
||||
# Andere selbst gehostete Apps im Menü der Seitenleiste.
|
||||
# Format: Name|URL|Emoji – mehrere durch Komma. Leer = kein Menü.
|
||||
EXTERNAL_APPS=
|
||||
|
||||
# ── Features ─────────────────────────────────────────────────────────────────
|
||||
# ── Office (optional) ─────────────────────────────────────────────────────────
|
||||
# Leer = aus. Container-Schnipsel: README.md
|
||||
OFFICE_PROVIDER= # collabora | onlyoffice (auch Euro-Office)
|
||||
OFFICE_URL= # Backend → Office
|
||||
OFFICE_PUBLIC_URL= # Browser → Office; leer = wie OFFICE_URL
|
||||
# Office → Aether; leer = PUBLIC_URL.
|
||||
# NICHT localhost, NICHT der veröffentlichte Port – beides scheitert.
|
||||
OFFICE_WOPI_URL=
|
||||
OFFICE_ALLOWED_HOSTS= # gegen SSRF; Host aus OFFICE_URL zählt immer
|
||||
OFFICE_INSECURE_TLS=false # nur für Tests mit selbstsigniertem Zertifikat
|
||||
|
||||
# Nur für den Collabora-Container aus deploy/docker-compose.yml:
|
||||
OFFICE_ALIASGROUP=http://app:8080
|
||||
OFFICE_SSL=false
|
||||
OFFICE_SSL_TERMINATION=false # produktiv true; false ohne HTTPS davor
|
||||
OFFICE_PORT=9980
|
||||
|
||||
# ── Später ────────────────────────────────────────────────────────────────────
|
||||
# MEILISEARCH_URL=http://meilisearch:7700
|
||||
# MEILISEARCH_KEY=
|
||||
|
||||
# ── App-Umschalter ────────────────────────────────────────────────────────────
|
||||
# Andere selbst gehostete Apps, die im Menü oben in der Seitenleiste erscheinen.
|
||||
# Format: Name|URL|Emoji – mehrere durch Komma getrennt. Leer = kein Menü.
|
||||
# Beispiel: EXTERNAL_APPS=InkNote|https://notes.honeyy.duckdns.org|📓
|
||||
EXTERNAL_APPS=
|
||||
|
||||
# ── OIDC: bestehendes Konto verbinden ───────────────────────────────────────
|
||||
# Es gibt schon ein Konto mit demselben Benutzernamen, aber ohne Bindung an den
|
||||
# Identitätsanbieter – was soll passieren?
|
||||
#
|
||||
# false (Voreinstellung): Es entsteht ein ZWEITES Konto. Da der Name vergeben
|
||||
# ist, heißt es "name2" – leer, ohne Adminrechte, ohne deine Dateien.
|
||||
# true: Das bestehende Konto wird mit der Identität verbunden. Dateien,
|
||||
# Adminrecht und Freigaben bleiben; ab dann meldest du dich darüber an.
|
||||
#
|
||||
# Auf "true" nur, wenn du dem Anbieter glaubst, dass "marc" bei ihm derselbe
|
||||
# "marc" ist wie hier – also bei einem eigenen Anbieter (PocketID, Authentik),
|
||||
# dessen Konten du selbst anlegst. Bei einem Anbieter mit freier Registrierung
|
||||
# wäre es die Übernahme fremder Konten.
|
||||
#
|
||||
# Verbunden wird nur, was noch KEINE Bindung hat – ein Konto, das schon zu einer
|
||||
# anderen Identität gehört, wird nie überschrieben.
|
||||
# OIDC_LINK_BY_USERNAME=true
|
||||
|
||||
# ── Wo die Dateien liegen ────────────────────────────────────────────────────
|
||||
# Ein gewöhnliches Verzeichnis auf dem Wirt, kein Docker-Volume. Damit kommst
|
||||
# du per SFTP, rsync oder im Dateimanager an deine Dateien – sie liegen dort
|
||||
# als echte Ordner mit echten Namen (users/<name>/home/…).
|
||||
#
|
||||
# Nur lesend benutzen: Wer von Hand hineinschreibt, hat eine Datei, die die
|
||||
# Cloud nicht kennt. Zum Hineinlegen ist WebDAV der Weg.
|
||||
DATA_PATH=/pfad/zu/aether-data
|
||||
|
||||
# Der Container läuft unter dieser Kennung, damit die Dateien im Verzeichnis
|
||||
# oben **dir** gehören und nicht einem Container-Nutzer. `id -u` und `id -g`
|
||||
# verraten deine.
|
||||
APP_UID=1000
|
||||
APP_GID=1000
|
||||
|
||||
# Port auf dem Wirt – gebunden auf **loopback**, davor gehört dein Reverse
|
||||
# Proxy. Im Container bleibt es immer 8080; hier steht nur, unter welchem Port
|
||||
# der Wirt ihn anbietet.
|
||||
APP_PORT=8080
|
||||
|
||||
# ── Volltextsuche über den Inhalt (OCR) ──────────────────────────────────────
|
||||
# Holt den Text aus PDFs und Bildern, damit auch ein Scan namens
|
||||
# "scan_0042.pdf" über seinen Inhalt auffindbar ist. Das Original wird dabei
|
||||
# nicht verändert – der Text landet daneben in der Datenbank.
|
||||
#
|
||||
# Standardmäßig an. Fehlen ocrmypdf/tesseract im Image, schaltet sich der
|
||||
# Arbeiter beim Start von selbst ab und die Cloud läuft ohne Volltext weiter.
|
||||
# OCR_ENABLED=false
|
||||
|
||||
# Sprachmodelle für tesseract. Im Image liegen deu und eng; weitere brauchen
|
||||
# ein zusätzliches apk-Paket (tesseract-ocr-data-<sprache>) im Dockerfile.
|
||||
# OCR_LANGUAGES=deu+eng
|
||||
|
||||
# Höchstzahl erkannter Seiten je Datei. OCR kostet rund eine Minute je
|
||||
# gescannter Seite – ohne Grenze blockiert ein dickes Handbuch die
|
||||
# Warteschlange für alles andere. 0 = unbegrenzt.
|
||||
# OCR_MAX_PAGES=50
|
||||
|
||||
# Notbremse je Datei, falls eine einzelne Seite entgleist.
|
||||
# OCR_TIMEOUT=10m
|
||||
|
||||
# ── Office (optional) ────────────────────────────────────────────────────────
|
||||
# Leer = aus. Die Anwendung ist ohne Office vollständig.
|
||||
#
|
||||
# Beide Anbieter sprechen WOPI, es gibt also nur einen Adapter:
|
||||
# collabora – LibreOffice-Kern, ~1 GB Arbeitsspeicher, ODF nativ
|
||||
# onlyoffice – beste .docx/.xlsx-Treue, 2 GB Minimum / 4 GB empfohlen
|
||||
OFFICE_PROVIDER=
|
||||
OFFICE_URL=
|
||||
# Adresse, unter der der **Browser** den Office-Server erreicht. Leer = dieselbe
|
||||
# wie OFFICE_URL. Die beiden sind selten gleich: Im Compose-Netz heisst der
|
||||
# Server `collabora`, im Browser muss dort ein aufloesbarer Name stehen.
|
||||
OFFICE_PUBLIC_URL=
|
||||
# Adresse, unter der der **Office-Server** Aether erreicht. Leer = PUBLIC_URL.
|
||||
# Der am leichtesten uebersehene Weg: Der Office-Server holt die Datei selbst
|
||||
# ab, und aus seinem Container heraus ist „localhost" er selbst.
|
||||
# Laufen beide im selben Compose-Projekt, ist das der Dienstname: http://app:8080
|
||||
# Der veroeffentlichte Port (127.0.0.1:8090) taugt **nicht** – auf loopback
|
||||
# gebunden, aus einem Container also nicht erreichbar (ECONNREFUSED).
|
||||
OFFICE_WOPI_URL=
|
||||
# Adressen, die das Backend anfragen darf – gegen SSRF. Der Host aus OFFICE_URL
|
||||
# zählt immer dazu; hier kommt nur hinein, was zusätzlich erlaubt sein soll.
|
||||
OFFICE_ALLOWED_HOSTS=
|
||||
# Nur für den Testaufbau mit selbstsigniertem Zertifikat auf demselben Rechner.
|
||||
OFFICE_INSECURE_TLS=false
|
||||
# Für den mitgelieferten Collabora-Container (docker compose --profile office):
|
||||
# unter welcher Adresse er Aether erreicht. Punkte maskieren – Collabora liest
|
||||
# den Wert als regulären Ausdruck.
|
||||
OFFICE_ALIASGROUP=http://app:8080
|
||||
OFFICE_SSL=false
|
||||
# Endet HTTPS an deinem Reverse Proxy? Produktiv true, im reinen HTTP-Test
|
||||
# false – sonst verlangt Collabora vom Browser eine wss://-Verbindung, die es
|
||||
# nicht gibt, und der Editor bleibt leer.
|
||||
OFFICE_SSL_TERMINATION=false
|
||||
OFFICE_PORT=9980
|
||||
# ── WebDAV ────────────────────────────────────────────────────────────────────
|
||||
# Läuft unter /dav/, kein Schalter nötig. Der Proxy muss
|
||||
# PROPFIND/MKCOL/MOVE/COPY durchreichen.
|
||||
@@ -34,6 +34,16 @@ RUN apk add --no-cache ca-certificates tzdata && \
|
||||
chown -R aether:aether /data
|
||||
WORKDIR /app
|
||||
|
||||
# Wo die Blobs liegen. Steht **hier**, nicht nur in der .env: Die Voreinstellung
|
||||
# im Code ist "./data" – richtig für ein Binary, das man von Hand startet,
|
||||
# falsch im Container, wo daraus /app/data würde. Genau das ist beim ersten
|
||||
# Aufbau aus der schlanken .env passiert: Migrationen liefen durch, dann
|
||||
# "mkdir /app/data: permission denied". Das Abbild kennt seine eigene
|
||||
# Verzeichnisstruktur besser als jede Beispieldatei; eine .env darf es
|
||||
# weiterhin überschreiben.
|
||||
ENV STORAGE_PATH=/data \
|
||||
TMP_PATH=/data/tmp
|
||||
|
||||
# Tesseract vermisst beim allerersten Aufruf die OpenCL-Geräte und schreibt
|
||||
# dabei einen langen Diagnoseblock nach stderr. ocrmypdf ruft davor
|
||||
# `tesseract --list-langs` auf und liest die Antwort – der Block bringt seinen
|
||||
|
||||
Reference in new issue
Block a user