Files
composes/collabora/README.md
T

3.6 KiB

collabora

Collabora Online Development Edition (CODE): an online office suite for documents, spreadsheets and presentations. It holds no files itself; a WOPI host, a file server with Collabora integration, opens documents in it.

One container: collabora.

Setup

  1. Set COLLABORA_ALIASGROUP1 to the WOPI host's URL, COLLABORA_ADMIN_PASSWORD and COLLABORA_SERVER_NAME.
  2. Map the domain to port 9980 and deploy.
  3. In the WOPI host, set the Collabora server URL to the public https:// address of this domain.

Discovery: GET /hosting/discovery returns XML once the server is up. The image ships its own health check (coolwsd --probe, against /livez), so the compose file declares none.

WebSocket editing sessions go through Traefik's default routing; no extra labels are needed.

Environment

Variable Default Purpose
COLLABORA_ALIASGROUP1 — Allowed WOPI host, scheme://host:port; later comma-separated entries are aliases of it
COLLABORA_ADMIN_USERNAME / COLLABORA_ADMIN_PASSWORD admin / — Admin console at /browser/dist/admin/admin.html
COLLABORA_SERVER_NAME empty Public hostname; empty derives it from each request
COLLABORA_DICTIONARIES optional Space-separated spell-check languages; upstream's default list when unset

aliasgroup1 is the only access control on document editing: with no group set, CODE trusts whichever host connects first after each start. Entries are regular expressions, so https://.*\.example\.com:443 allows a whole domain. A second, unrelated WOPI host needs its own aliasgroup2 line in compose.yml.

extra_params is fixed in compose.yml: --o:ssl.enable=false serves plain HTTP on 9980 for Traefik to terminate TLS in front of it, and --o:ssl.termination=true makes CODE build https:// and wss:// URLs anyway. Without it the editor loads over HTTPS but fails on mixed-content WebSocket URLs.

The admin password fails fast if unset, because the console is served on the public domain.

Storage

None. Documents stay on the WOPI host; CODE's jails and cache are rebuilt on every start.

Isolation

CODE isolates each document process in a jail, choosing the first that works: a mount namespace, then a chroot built by coolforkit-caps, then landlock.

The compose file adds no capabilities and no security_opt. Docker's default seccomp profile blocks the unshare a mount namespace needs, so CODE falls back to the chroot. coolforkit-caps carries file capabilities CAP_CHOWN, CAP_FOWNER and CAP_SYS_CHROOT, all in Docker's default set, so it works unprivileged. MKNOD, which older CODE images needed, is no longer used.

The price is speed, not safety: without CAP_SYS_ADMIN the coolmount helper cannot bind-mount the system template, so each new jail copies it, and opening a document takes a little longer. The alternatives cost more: cap_add: SYS_ADMIN grants the container broad host-kernel powers, and upstream's cool-seccomp-profile.json, Docker's default list plus the six namespace and mount syscalls needed, must exist as a file on the host, which a Coolify compose deploy does not place there.

The startup log line creating usernamespace for mount user failed is this fallback, not a fault. Do not set no-new-privileges: coolforkit-caps gains its capabilities on exec, and without them CODE drops to the weaker landlock jail.

Image

collabora/code:latest is the only moving tag upstream publishes; releases are versioned YY.MM.x. The container keeps no state, so a new release needs only a redeploy.