Files
Aether/deploy/.env.example
T
marcandClaude Opus 5 9c5cda75d7 feat(office): Dokumente am Telefon als PDF ansehen statt bearbeiten
Am Finger öffnet ein Office-Dokument jetzt das gewandelte PDF im eigenen
Betrachter; "Edit" daneben führt trotzdem in den Editor. Mit Maus ändert
sich nichts.

Der Web-Editor ist eine vollständige Textverarbeitung – zwischen seinen
Leisten bleibt auf 400 Pixeln vom Dokument ein Rechteck. Collabora und
OnlyOffice verhalten sich gleich; deshalb kein besserer Bedienmodus,
sondern ein anderes Werkzeug. Gewandelt wird von dem Server, der auch
bearbeitet: Sonst sähe man unterwegs ein LibreOffice-Layout eines
Dokuments, für das man OnlyOffice gewählt hat.

Je Dokument gibt es GENAU EIN PDF, und das ist keine Frage des
Aufräumens, sondern des Schlüssels: previews/<id>.pdf trägt die Fassung
nicht im Namen, eine neue Fassung überschreibt. files.preview_version
sagt, ob das Abgelegte noch passt.

Sicherheit: Die Adresse, die OnlyOffice zurückgibt, wird von uns
abgerufen – der Wähler des Transports lässt nur OFFICE_ALLOWED_HOSTS zu,
zusätzlich eine ausdrückliche Prüfung mit Test. JWT-Signatur (HS256) für
die eigene API des Dokumentenservers. Fremde Kennung 404, ohne Anmeldung
401. Das Ergebnis muss mit %PDF- beginnen, sonst landete eine
Fehlerseite im Zwischenspeicher.

Gemessen gegen einen echten OnlyOffice-Server im Docker-Netz:
  erster Abruf 1,05 s -> zweiter 0,009 s
  erneut hochgeladen -> Fassung 2, preview_version 2, weiterhin 1 Datei
  GC: herrenloses PDF von vorgestern weg, echtes bleibt
  endgültig gelöscht -> PDF weg; Papierkorb -> PDF bleibt
  ohne Anmeldung 401, fremde Kennung 404, Nicht-Office 415

Dazu im Admin-Bereich neu: Platzbedarf der abgeleiteten Daten
(Vorschaubilder, PDFs, Profilbilder). Sie zählen gegen kein Kontingent –
ein Ordner, der wächst, ohne dass ihn jemand sieht, ist eine stille
Überraschung.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-08-31 23:30:49 +02:00

135 lines
7.7 KiB
Bash
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# Aether – alle Schalter. cp deploy/.env.example deploy/.env
#
# Zwei Fallen beim Bearbeiten:
# $ im Wert → als $$ schreiben, sonst schneidet Compose ab
# Kommentar hinter einem LEEREN Wert → der Kommentar wird zum Wert
# 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_ENV=production # development | production
APP_LISTEN_ADDR=:8080 # im Container; der Proxy leitet hierher
PUBLIC_URL=https://cloud.example.com
# IPs/CIDRs der Proxys, denen X-Forwarded-For/-Proto geglaubt wird.
TRUSTED_PROXIES=172.18.0.1
# ── 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 – nur ein $ muss $$ heißen oder der Wert in
# 'einfache Anführungszeichen'. Sonst schneidet Compose lautlos ab. (README)
DB_PASSWORD=changeme_strong_password
# ── Sitzung ───────────────────────────────────────────────────────────────────
SESSION_SECRET=changeme_generate_with_openssl_rand_hex_32 # openssl rand -hex 32
SESSION_MAX_AGE=86400 # Sekunden
# ── 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
# Frühere Fassungen je Datei. Greift nur bei eingeschaltetem „Keep versions".
MAX_VERSIONS_KEPT=5
# Port auf dem Wirt. Im Container bleibt es 8080.
APP_PORT=8080
# Wer den Port erreichen darf. 127.0.0.1 = nur dieser Rechner (Vorgabe).
# 0.0.0.0 = das ganze Netz – dann unverschlüsselt.
APP_BIND=127.0.0.1
# ── Erster Start ──────────────────────────────────────────────────────────────
# Legt den Admin an. Danach ADMIN_PASSWORD leeren.
# Auch hier: ein $ muss $$ heißen (siehe DB_PASSWORD).
ADMIN_USERNAME=admin
ADMIN_PASSWORD=changeme_strong_admin_password
# ── 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 # Adresse, nicht der Name
# 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
# Beschriftung des Knopfes auf der Anmeldeseite.
# OIDC_BUTTON_LABEL=Anmelden mit PocketID
# ── HoneyOS-Leiste ────────────────────────────────────────────────────────────
# Ursprung, von dem die Leiste geladen wird. Wird an zwei Stellen gebraucht und
# kommt deshalb aus einer Quelle: die CSP erlaubt ihn (script-src +
# connect-src), und die Oberflaeche laedt das Skript von dort nach.
#
# Wirkt beim **Neustart** — kein Neubau noetig.
# Leer = keine Leiste, und die CSP bleibt so eng wie ohne sie.
HONEYBAR_ORIGIN=https://os.example.com
# Ausweis, mit dem sich die Leiste die App-Liste holt. Muss zu HONEYOS_APPS_KEY
# drueben passen. Nur noetig, wenn HoneyOS auf einer anderen Site liegt als
# Aether — dann schickt der Browser die HoneyOS-Sitzung nicht mit.
#
# Gleiche Site (os.beispiel.duckdns.org + cloud.beispiel.duckdns.org): kann leer
# bleiben, die Sitzung reicht.
HONEYBAR_KEY=
# ── 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
# ── App-Umschalter ────────────────────────────────────────────────────────────
# Andere selbst gehostete Apps im Menü der Seitenleiste.
# Format: Name|URL|Emoji – mehrere durch Komma. Leer = kein Menü.
EXTERNAL_APPS=
# ── Office (optional) ─────────────────────────────────────────────────────────
# Leer = aus, auch wenn ein Office-Container läuft. Schnipsel: README.md
# collabora | onlyoffice (auch Euro-Office)
OFFICE_PROVIDER=
# Backend → Office. Collabora lauscht auf 9980, OnlyOffice/Euro-Office auf 80.
OFFICE_URL=
# Browser → Office; leer = wie OFFICE_URL
OFFICE_PUBLIC_URL=
# Office → Aether; leer = PUBLIC_URL.
# Weder localhost noch der veröffentlichte Port – beides scheitert.
# **Bei Collabora die öffentliche Adresse der Cloud**, nicht app:8080: Aus
# diesem Wert baut Collabora sein frame-ancestors, und der Browser darf den
# Rahmen sonst nicht zeigen. Siehe README, Abschnitt Office.
OFFICE_WOPI_URL=
# Gegen SSRF; der Host aus OFFICE_URL zählt immer dazu.
OFFICE_ALLOWED_HOSTS=
# Nur OnlyOffice/Euro-Office, mind. 32 Zeichen. Muss mit JWT_SECRET des
# Office-Containers übereinstimmen: Ohne ihn schlägt das Wandeln nach PDF fehl
# (der Server antwortet `{"error":-8}`). Für den WOPI-Weg wird er nicht
# gebraucht, der hat eigene Token.
OFFICE_JWT_SECRET=
OFFICE_INSECURE_TLS=false # nur für Tests mit selbstsigniertem Zertifikat
# Nur für den Collabora-Container aus deploy/docker-compose.yml.
# Derselbe Host wie in OFFICE_WOPI_URL, aber als regulärer Ausdruck: Punkte
# maskieren, Port anhängen. Beispiel:
# OFFICE_ALIASGROUP=https://cloud\.example\.com:443
# Fehlt er, lehnt Collabora mit „No authorized hosts found" ab.
OFFICE_ALIASGROUP=http://app:8080
OFFICE_SSL=false
OFFICE_SSL_TERMINATION=false # true nur, wenn davor wirklich HTTPS endet
OFFICE_PORT=9980
# ── Später ────────────────────────────────────────────────────────────────────
# MEILISEARCH_URL=http://meilisearch:7700
# MEILISEARCH_KEY=
# ── WebDAV ────────────────────────────────────────────────────────────────────
# Läuft unter /dav/, kein Schalter nötig. Der Proxy muss
# PROPFIND/MKCOL/MOVE/COPY durchreichen.