Files
Aether/deploy/.env.example
T
HoneyandClaude Opus 5 31a027c93a feat(aether): initial commit – self-hosted Cloud, Phasen 1–7
Go-Backend (chi, pgx, golang-migrate) + React/TS-Frontend als PWA.
Enthalten: Auth inkl. OIDC, Dateien mit Versionen und Papierkorb,
Freigaben (Links + intern), WebDAV, Gruppenordner, Admin/Theming,
Volltextsuche mit OCR, eigener PDF-Betrachter und WOPI-Office
(Collabora/OnlyOffice).

Nicht im Repo: deploy/.env (Sitzungsschlüssel, DB- und Admin-Passwort)
sowie alle Daten- und Build-Verzeichnisse – siehe .gitignore.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-08-24 09:25:36 +02:00

161 lines
9.0 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 – Environment Variables
# Copy to .env and fill in values. Never commit .env!
# ── 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.
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
TRUSTED_PROXIES=172.18.0.1
# ── Database ─────────────────────────────────────────────────────────────────
DB_HOST=postgres
DB_PORT=5432
DB_NAME=aether
DB_USER=aether
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)
# ── Storage ───────────────────────────────────────────────────────────────────
STORAGE_PATH=/data
TMP_PATH=/data/tmp
# ── Admin seed ────────────────────────────────────────────────────────────────
# Used only on first startup to create the initial admin account.
# Remove or leave blank after first start.
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_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
# ── WebDAV ────────────────────────────────────────────────────────────────────
# Erreichbar unter /dav/ (Basic Auth, Username + Passwort). Kein Setting nötig.
# Reverse Proxy muss PROPFIND/MKCOL/MOVE/COPY durchreichen.
# ── 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.)
# ── Features ─────────────────────────────────────────────────────────────────
# 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