From 1064a4d8e8b7659985821b20e75968ca1152fed9 Mon Sep 17 00:00:00 2001 From: Christoph Date: Sun, 19 Jul 2026 08:33:01 +0200 Subject: [PATCH] inmitial commit --- Installationsanleitung_Euro-Office.docx | Bin 0 -> 15659 bytes Installationsanleitung_Euro-Office.md | 411 ++++++++++++++++++++++++ 2 files changed, 411 insertions(+) create mode 100644 Installationsanleitung_Euro-Office.docx create mode 100644 Installationsanleitung_Euro-Office.md diff --git a/Installationsanleitung_Euro-Office.docx b/Installationsanleitung_Euro-Office.docx new file mode 100644 index 0000000000000000000000000000000000000000..ed7059cd9362974d1ba123c92c6a183b24fb4eea GIT binary patch literal 15659 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∋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 | Hostname des Euro-Office DocumentServers | `eo-ds.ndnaht.de` | +| `` | Hostname der bestehenden Nextcloud-Instanz | `cloud.ndnaht.de` | +| `` | Öffentliche IPv4-Adresse des Servers | `135.181.90.132` | +| `` | Öffentliche IPv6-Adresse des Servers | `2a01:4f9:c014:1ba8::1` | +| `` | Arbeitsverzeichnis für Docker-Compose-Stack | `/opt/euro-office` | +| `` | Verzeichnis der Apache-vHost-Konfigurationsdateien | `/usr/local/apache2/conf/vhosts` | +| `` | Lokaler Port, auf den der Container gemappt wird | `8080` | +| `` | Fester Name der Docker-Netzwerk-Bridge | `br-euroffice` | +| `` | Verzeichnis mit TLS-Zertifikat (hier: dehydrated) | `/var/lib/dehydrated/certs/` | +| `` | Docroot-Verzeichnis der Nextcloud-Installation | `/var/www/cloud.ndnaht.de/htdocs` | +| `` | Pfad der Nextcloud-Logdatei | `/var/www/cloud.ndnaht.de/logs/cloud.log` | +| `` | Pfad zum PHP-CLI-Binary | `/usr/local/php/bin/php` | +| `` | Gemeinsames Secret zwischen DocumentServer und Nextcloud | wird generiert (siehe Schritt 3) | + +--- + +## 2. Voraussetzungen + +- **Betriebssystem:** Debian 13 (getestet), amd64 oder arm64 +- **Docker Engine** (Community Edition) inkl. **Compose-Plugin v2**, installiert über das offizielle Docker-Repository: + ``` + deb [arch=amd64 signed-by=/etc/apt/keyrings/docker.asc] https://download.docker.com/linux/debian trixie stable + ``` +- **Mindestens 4 GB RAM** (8 GB empfohlen für Mehrbenutzerbetrieb), 10 GB freier Plattenplatz +- **Bestehende Nextcloud-Instanz** (getestet mit Nextcloud 34), erreichbar über Apache2, mit SSH-/`occ`-Zugriff +- **DNS-Eintrag** für ``, zeigt auf `` (bzw. ``) +- **Gültiges TLS-Zertifikat** für `` (hier über [dehydrated](https://github.com/dehydrated-io/dehydrated) verwaltet) +- **Apache2** bereits installiert und aktiv, mit folgenden Modulen aktiviert: + `proxy`, `proxy_http`, `proxy_wstunnel`, `ssl`, `headers`, `rewrite` +- **Firewall-Hinweis:** Falls der Server eine eigene iptables/nftables-Firewall betreibt + (Eigenbau-Skript, CSF, ufw o. ä.), die *nicht* automatisch mit Docker zusammenarbeitet, + siehe Abschnitt 8 ("Firewall-Anpassung für Docker-Bridge-Netzwerke"). Ohne diesen Schritt + ist der Container u. U. nicht einmal vom Host selbst erreichbar. + +--- + +## 3. Arbeitsverzeichnis und Secrets anlegen + +```bash +sudo mkdir -p +cd +``` + +JWT-Secret generieren und in `.env` ablegen (wird von Docker Compose automatisch eingelesen): + +```bash +echo "EO_JWT_SECRET=$(openssl rand -hex 32)" | sudo tee .env +sudo chmod 600 .env +``` + +> Diesen Wert später 1:1 in die Nextcloud-Konfiguration übernehmen (Schritt 10). + +--- + +## 4. docker-compose.yaml + +Der Container wird **nicht** direkt öffentlich exponiert, sondern nur auf `127.0.0.1` +gebunden — Apache übernimmt als Reverse-Proxy die öffentliche Erreichbarkeit inkl. TLS. +Das Docker-Netzwerk bekommt einen **festen Bridge-Namen**, damit Firewall-Regeln, die +auf den Interface-Namen verweisen, auch nach einem Neuaufbau des Netzwerks gültig bleiben. + +```yaml +services: + euro-office: + image: ghcr.io/euro-office/documentserver:latest + container_name: euro-office-ds + restart: unless-stopped + environment: + - JWT_ENABLED=true + - JWT_SECRET=${EO_JWT_SECRET} + # EXAMPLE_ENABLED bewusst NICHT gesetzt (=false) -> kein offenes Beispiel-App in Produktion + ports: + - "127.0.0.1::80" + volumes: + - eo_data:/var/lib/euro-office/documentserver + - eo_logs:/var/log/euro-office/documentserver + - eo_config:/etc/euro-office/documentserver + networks: + - euroffice + healthcheck: + test: ["CMD-SHELL", "curl -sf http://localhost/healthcheck || exit 1"] + interval: 30s + timeout: 10s + retries: 5 + start_period: 60s + +volumes: + eo_data: + eo_logs: + eo_config: + +networks: + euroffice: + driver: bridge + driver_opts: + com.docker.network.bridge.name: +``` + +Datei anlegen: + +```bash +cd +sudo tee docker-compose.yaml > /dev/null << 'EOF' +# --- Inhalt wie oben, Platzhalter durch tatsächliche Werte ersetzt --- +EOF +``` + +Konfiguration prüfen, bevor gestartet wird (zeigt das aufgelöste `JWT_SECRET`): + +```bash +sudo docker compose config +``` + +--- + +## 5. Container starten + +```bash +cd +sudo docker compose up -d +sudo docker compose ps +``` + +Erwartet: Status `Up ... (healthy)` nach ca. 60–90 Sekunden (erste Fontgenerierung dauert etwas). + +Lokalen Health-Check testen: + +```bash +curl -i --max-time 5 http://127.0.0.1:/healthcheck +``` + +Erwartet: `HTTP/1.1 200 OK` + +> **Falls dieser Test hängt/fehlschlägt (Timeout oder Connection Reset), obwohl +> `docker compose ps` bereits `healthy` zeigt:** Das deutet auf ein Firewall-Problem hin — +> siehe Abschnitt 8. + +--- + +## 6. Apache-Module prüfen/aktivieren + +```bash +sudo a2enmod proxy proxy_http proxy_wstunnel ssl headers rewrite +sudo systemctl restart apache2 +sudo systemctl status apache2 --no-pager +``` + +--- + +## 7. Apache-vHost anlegen + +Datei `/.conf`: + +```apache +:80 []:80> + ServerName + RewriteEngine on + RewriteCond %{HTTPS} !=on + RewriteRule (.*) https://%{SERVER_NAME}%{REQUEST_URI} [R=301,L] + CustomLog /var/log/apache2/-access.log combined + ErrorLog /var/log/apache2/-error.log + + +:443 []:443> + ServerName + + SSLEngine on + SSLCertificateFile /fullchain.pem + SSLCertificateKeyFile /privkey.pem + + ProxyPreserveHost On + ProxyRequests Off + + # WebSocket-Verbindungen (Co-Editing) an proxy_wstunnel weiterreichen + RewriteEngine On + RewriteCond %{HTTP:Upgrade} =websocket [NC] + RewriteRule ^/(.*) ws://127.0.0.1:/$1 [P,L] + RewriteCond %{HTTP:Upgrade} !=websocket [NC] + RewriteRule ^/(.*) http://127.0.0.1:/$1 [P,L] + + # Wichtig: DocumentServer muss wissen, dass er hinter TLS läuft, + # sonst generiert er interne Editor-/Cache-URLs mit http:// statt https:// + # ("Mixed Content", Editor kann Dokumente nicht laden/herunterladen). + RequestHeader set X-Forwarded-Proto "https" + RequestHeader set X-Forwarded-Host "" + RequestHeader set X-Forwarded-Port "443" + + ProxyPass / http://127.0.0.1:/ retry=0 + ProxyPassReverse / http://127.0.0.1:/ + + # Große Uploads (Dokumente) erlauben + LimitRequestBody 0 + + CustomLog /var/log/apache2/-access.log combined + ErrorLog /var/log/apache2/-error.log + +``` + +Aktivieren und testen: + +```bash +sudo apachectl configtest +sudo systemctl reload apache2 +``` + +Erreichbarkeit von außen prüfen: + +```bash +curl -i https:///healthcheck +``` + +Erwartet: `HTTP/1.1 200 OK` + +--- + +## 8. Firewall-Anpassung für Docker-Bridge-Netzwerke + +**Nur relevant, wenn eine eigene Firewall-Lösung eingesetzt wird, die den Datenverkehr über +Docker-Bridge-Interfaces nicht automatisch zulässt** (z. B. eigene iptables/nftables-Skripte +mit einer restriktiven `OUTPUT`/`FORWARD`-Policy). + +### Symptom + +- `docker compose ps` zeigt den Container als `healthy` (interner Check funktioniert) +- Ein `curl` **von außerhalb des Containers** auf `127.0.0.1:` oder die + Container-IP hängt oder liefert `Connection reset by peer` / `Operation timed out` +- `ping` auf die Container-IP funktioniert (ICMP ist oft separat erlaubt), TCP jedoch nicht + +### Ursache + +Docker bindet Container-Ports über einen `docker-proxy`-Prozess bzw. NAT-Regeln, die +Datenverkehr über das jeweilige Docker-Bridge-Interface (`br-...`) leiten. Eine restriktive +Firewall mit interface-spezifischen `ACCEPT`-Regeln (z. B. nur für `eth0`) und einer +abschließenden `DROP`-Regel lässt diesen Bridge-Verkehr nicht automatisch durch. + +### Lösung + +1. Docker-Netzwerk mit **festem Bridge-Namen** betreiben (siehe Abschnitt 4, + `com.docker.network.bridge.name: `) — verhindert, dass sich der + Interface-Name bei jedem Neuaufbau des Netzwerks ändert. +2. In der Firewall-Konfiguration eine **explizite Ausnahme für dieses eine Interface** + eintragen (kein Wildcard wie `br+`, das würde auch fremde/zukünftige Bridges ungefiltert + durchlassen). Je nach Firewall-Lösung z. B.: + - Eigenbau-Skript mit `unprotected_ifs`-Variable: `unprotected_ifs=""` + - iptables direkt: gezielte `ACCEPT`-Regeln für `-i ` / `-o ` + in den Chains `INPUT`, `OUTPUT` und `FORWARD` +3. Firewall neu laden und Docker-Daemon **danach** neu starten, damit Docker seine eigenen + iptables-Chains (`DOCKER`, `DOCKER-FORWARD`, `DOCKER-USER`, …) neu aufbaut: + ```bash + sudo systemctl restart + sudo systemctl restart docker + cd && sudo docker compose up -d + ``` +4. **Startreihenfolge dauerhaft absichern**, damit das Problem nach einem Server-Reboot nicht + erneut auftritt — Docker soll immer *nach* der Firewall starten: + ```bash + sudo mkdir -p /etc/systemd/system/docker.service.d/ + sudo tee /etc/systemd/system/docker.service.d/after-firewall.conf > /dev/null << 'EOF' + [Unit] + After=.service + Wants=.service + EOF + sudo systemctl daemon-reload + ``` + +### Restrisiko + +Ein manueller Neustart der Firewall **während Docker bereits läuft** stört bestehende, +schon aktive Container-Verbindungen in der Regel nicht. Wird jedoch **danach** ein neues +Docker-Netzwerk angelegt (z. B. `docker compose down && up`, oder ein neuer Compose-Stack), +kann die Regel-Einfügung fehlschlagen (`Failed to Setup IP tables: ... No chain/target/match +by that name`), weil Dockers eigene Chains beim Firewall-Neuaufbau entfernt wurden. In diesem +Fall genügt es, den Docker-Daemon einmal neu zu starten und den Stack erneut zu starten: + +```bash +sudo systemctl restart docker +cd && sudo docker compose up -d +``` + +### Verifikation nach einem vollständigen Server-Reboot + +```bash +sudo reboot +# nach dem Reboot, neu verbinden: +systemctl status --no-pager +systemctl status docker.service --no-pager +sudo docker compose -f /docker-compose.yaml ps +curl -i --max-time 5 https:///healthcheck +ip a | grep -A2 +sudo docker network ls +``` + +--- + +## 9. Nextcloud-Connector-App installieren + +Die Euro-Office-Integration ist im offiziellen Nextcloud App Store gelistet. + +**Über die Weboberfläche:** + +1. Als Administrator einloggen +2. Profilbild (oben rechts) → **Apps** +3. Kategorie **„Büro & Text"** auswählen +4. **„Euro-Office"** suchen → **„Download and enable"** + +**Alternativ über die Konsole (`occ`):** + +```bash +cd +sudo -u www-data occ app:install eurooffice +``` + +`app:install` lädt die App aus dem Nextcloud App Store herunter **und** aktiviert sie in +einem Schritt. Falls die App bereits heruntergeladen, aber nur deaktiviert ist, genügt +stattdessen: + +```bash +sudo -u www-data occ app:enable eurooffice +``` + +**Kontrolle per SSH:** + +```bash +sudo -u www-data /occ app:list | grep -i eurooffice +``` + +Erwartet: Eintrag unter *Enabled*, z. B. `eurooffice: 11.0.1` + +--- + +## 10. Nextcloud konfigurieren (DocumentServer-URL + JWT-Secret) + +Zuerst prüfen, welche Config-Keys die App verwendet: + +```bash +cd +sudo -u www-data occ config:list eurooffice +``` + +DocumentServer-URL setzen: + +```bash +sudo -u www-data occ config:app:set eurooffice DocumentServerUrl --value="https:///" +``` + +JWT-Secret setzen (identischer Wert wie in `/.env`, Variable `EO_JWT_SECRET`): + +```bash +sudo grep EO_JWT_SECRET /.env +sudo -u www-data occ config:app:set eurooffice jwt_secret --value="" +``` + +Kontrolle: + +```bash +sudo -u www-data occ config:list eurooffice +``` + +--- + +## 11. Funktionstest + +1. In Nextcloud ein Office-Dokument (`.docx`, `.xlsx`, `.pptx`) öffnen +2. Der Euro-Office-Editor sollte sich im Browser öffnen und das Dokument anzeigen + +**Falls die Meldung „Herunterladen ist fehlgeschlagen" erscheint:** + +Browser-Entwicklerkonsole (F12) prüfen. Eine Meldung wie +*„Laden von gemischten aktiven Inhalten … wurde blockiert"* (Mixed Content) weist darauf hin, +dass der DocumentServer interne URLs mit `http://` statt `https://` erzeugt. Prüfen, ob die +`X-Forwarded-*`-Header im vHost (Abschnitt 7) korrekt gesetzt sind, danach: + +```bash +sudo apachectl configtest +sudo systemctl reload apache2 +``` + +Browser-Hard-Reload (`Strg+Shift+R`) und Dokument erneut öffnen. + +--- + +## 12. Wartung / Hinweise + +- **Volumes:** `eo_data`, `eo_logs`, `eo_config` (benannte Docker-Volumes) enthalten + Konfiguration, Cache und Logs. Für Backups: `docker run --rm -v :/data -v $(pwd):/backup alpine tar czf /backup/.tar.gz -C /data .` +- **Updates:** `docker compose pull && docker compose up -d` +- **Logs im Container:** + ```bash + sudo docker compose exec euro-office find /var/log/euro-office -iname "*.log" + ``` +- **EXAMPLE_ENABLED:** bewusst nicht gesetzt/aktiviert — die Beispiel-App hat keine + Zugriffskontrolle und darf nicht öffentlich erreichbar sein.