diff --git a/Network.md b/Network.md index 7007e5e..5d39521 100644 --- a/Network.md +++ b/Network.md @@ -27,6 +27,12 @@ sudo netplan apply Config: `/etc/caddy/Caddyfile` ``` +{ + servers { + protocols h1 h2 + } +} + haos.alogins.net { reverse_proxy http://192.168.1.141:8123 { header_up X-Forwarded-For {remote_host} @@ -82,6 +88,8 @@ vui4.alogins.net { reverse_proxy localhost:58959 } sudo systemctl enable --now caddy ``` +**HTTP/3 disabled globally** — the top-level `protocols h1 h2` option forces HTTP/1.1 and HTTP/2 only. OnlyOffice editor assets stall over HTTP/3 on distant connections (Caddy aborts with `writing: timeout: no recent network activity`), which breaks the Seafile → OnlyOffice flow. HTTP/2 handles the same payloads without issue. + ### Hairpin NAT The router does not support hairpin NAT — the server cannot reach its own public IP from within the LAN. Services that need to call back to a public domain from the host or from Docker containers must use local overrides. @@ -94,13 +102,16 @@ Add to `/etc/hosts` on the host for any domain that needs to be reached locally: 127.0.0.1 vw.alogins.net ``` -For Docker containers, use `extra_hosts` in the compose file: +For Docker containers, use `extra_hosts` in the compose file — routes to the host's Caddy via the Docker bridge gateway: ```yaml extra_hosts: - "docs.alogins.net:host-gateway" + - "office.alogins.net:host-gateway" ``` +Applied in both directions of the Seafile ⇄ OnlyOffice integration: the `seafile` container reaches `office.alogins.net` to download files after a save callback, and the `seafile-onlyoffice` container reaches `docs.alogins.net` to post callbacks. Without the extra_hosts the requests try the public IP and hang ~134s before timing out. + **Port forwarding requirements:** - Ports **80** and **443** forwarded on the router (source and target, remote IP empty) - Port **10051** forwarded for Zabbix active agent connections diff --git a/Seafile.md b/Seafile.md index 0eb9b1e..56615c3 100644 --- a/Seafile.md +++ b/Seafile.md @@ -118,7 +118,62 @@ ONLYOFFICE_EDIT_FILE_EXTENSION = ('docx', 'pptx', 'xlsx') ONLYOFFICE_JWT_SECRET = '' ``` -**Hairpin NAT fix**: OnlyOffice server must call back to Seafile to download files and post save events. Since the public IP is unreachable from inside Docker, `onlyoffice.yml` uses `extra_hosts: docs.alogins.net:host-gateway` so callbacks route via the host's Caddy instead of the public IP. +**Hairpin NAT fix**: hairpin routing affects both directions of the integration: +- `onlyoffice.yml` → `docs.alogins.net:host-gateway` (OnlyOffice fetches files from Seafile and posts save callbacks). +- `seafile-server.yml` → `office.alogins.net:host-gateway` (Seahub downloads the saved file from OnlyOffice's cache after a save callback). + +Without both, save callbacks time out (~134s), OnlyOffice retries, hits the backoff limit, and drops the edit into `forgotten/` — the file on disk stays at the old version and the editor shows "the file version has been changed" on reopen. + +## Troubleshooting + +### "Loading spreadsheet" hangs forever + +OnlyOffice editor assets (e.g. `fonts_ie.js`) served over HTTP/3 can stall on distant/lossy connections — Caddy aborts with `writing: timeout: no recent network activity`. Fix: disable HTTP/3 globally in `/etc/caddy/Caddyfile`: + +``` +{ + servers { + protocols h1 h2 + } +} +``` + +Browsers cache the `Alt-Svc: h3` hint for 30 days, so after reloading Caddy fully quit the browser (or test in a private window) to drop the cached hint. + +### "The file version has been changed" loop on reopen + +Caused by Seahub's save callback timing out (hairpin NAT, see above). Symptoms in logs: + +- `seahub.log`: `ConnectTimeoutError: Connection to office.alogins.net timed out` +- `seahub.access.log`: `POST /onlyoffice/editor-callback/ ... 500 285 ... 134.xxx` (seconds) +- `onlyoffice` container: `commandSfcCallback backoff limit exceeded` → `storeForgotten` +- Files accumulate in `/var/lib/onlyoffice/documentserver/App_Data/cache/files/forgotten//output.xlsx` + +After adding the `office.alogins.net:host-gateway` extra_host and recreating the seafile container, clear the stuck state: + +```bash +# 1. Inspect or recover any forgotten edits first +docker exec seafile-onlyoffice ls /var/lib/onlyoffice/documentserver/App_Data/cache/files/forgotten/ + +# 2. Wipe OnlyOffice's forgotten cache +docker exec seafile-onlyoffice sh -c \ + 'rm -rf /var/lib/onlyoffice/documentserver/App_Data/cache/files/forgotten/*' + +# 3. Wipe Seafile's cached doc_keys so fresh sessions generate new ones +PW=$(grep INIT_SEAFILE_MYSQL_ROOT_PASSWORD ~/agap_git/seafile/.env | cut -d= -f2) +docker exec seafile-mysql mysql -uroot -p"$PW" -e \ + 'DELETE FROM onlyoffice_onlyofficedockey;' seahub_db +``` + +Seafile stores the `(repo_id, file_path) → doc_key` mapping in `seahub_db.onlyoffice_onlyofficedockey`. + +### OnlyOffice degraded after long uptime + +After weeks without restart, `docservice` leaks AMQP heartbeats (`[AMQP] conn error Error: Heartbeat timeout` in `/var/log/onlyoffice/documentserver/docservice/out.log`) and Socket.IO sessions fail (`io.connection_error ... Transport unknown`). Restart clears it: + +```bash +cd ~/agap_git/seafile && docker compose restart onlyoffice +``` ## Notes