Introduction
We are talking about the infamous:
“Slow Kit jail setup with copying, cannot bind-mount.”
Inside the official collabora/code Docker image, coolwsd performs a startup self-test to determine whether the system supports bind-mounts inside the jailed environment.
Users see an error in the GUI, even on privileged containers.
The test is executed via /usr/bin/coolmount as UID 65534 (nobody), which has zero effective capabilities inside the container.
Because UID 65534 cannot perform any mount operations in Docker, the test always fails, causing Collabora to disable mount_jail_tree and fall back to slow file-copy behavior.
This affects all standard Docker deployments , even privileged: true ones.
Honestly I can’t think of how to screw this up and I believe it might be some issue in the coding, but I might be wrong..
here is how I solved the issue and you might solve it too. I’m looking forward for some feedback and see if am hallucinating or if its considered solid advice (maybe its by design, I don’t quite know)
I use collabora with nextcloud and run a yml file with all the various nextcloud containers, including collabora.
Current env is boring plain ubuntu server 24.04.3 LTS running Client: Docker Engine - Community, Version: 29.1.2, the most standard setup you can imagine.
Collabora is currently on Collabora Online Development Edition 25.04.7.3 a0576a3364
this is a snippet from my patched docker-compose.yml (again, plain and simple)
collabora:
image: collabora/code:latest
container_name: collabora
restart: always
privileged: true
environment:
- extra_params=--o:ssl.enable=false
ports:
- "9980:9980"
networks:
- default
volumes:
- /srv/nextcloud/collabora/coolmount-patch/coolmount:/usr/bin/coolmount:ro
- /srv/nextcloud/collabora/coolmount-patch/coolmount.real:/usr/bin/coolmount.real:ro
Detailed explanation
At startup, Collabora executes:
coolmount -b systemplate → cool_test_mount
coolmount -r systemplate → cool_test_mount
coolmount -u cool_test_mount
However:
- The test process runs as UID 65534
- The container filesystem is read-only, so setcap cannot modify the binary
- Therefore the test always returns a non-zero exit code
- Collabora assumes the kernel does not support jailed mounts
- mount_jail_tree is disabled → performance suffers (file copying instead of bind mounts)
Real document operations, however, run as user cool (UID 1001) and would work correctly if the startup test did not incorrectly disable the feature.
Workaround
Override /usr/bin/coolmount with a wrapper script before Collabora starts.
This wrapper:
- Detects the startup test (UID 65534 + cool_test_mount)
- Returns exit code 0 for that case only
- Delegates all real operations to the original ELF binary (coolmount.real)
- Allows coolmount.real to run with proper file capabilities (granted on the host)
Wrapper script
Path: /srv/collabora/coolmount-patch/coolmount
#!/bin/bash
LOG=/tmp/coolmount.log
uid_now="$(id -u)"
# Fake success only for the startup self-test (UID 65534 + cool_test_mount)
if [ "$uid_now" = "65534" ] && [[ " $* " == *"cool_test_mount"* ]]; then
echo "Self-test bypassed (UID 65534) at $(date)" >>"$LOG"
exit 0
fi
# Otherwise call the real mount helper
DIR="$(cd "$(dirname "$0")" && pwd)"
"$DIR/coolmount.real" "$@"
exit $?
Make it executable:
chmod +x /srv/collabora/coolmount-patch/coolmount
Extract the real binary:
docker cp collabora:/usr/bin/coolmount /srv/collabora/coolmount-patch/coolmount.real
Give the real binary capabilities on the host filesystem:
sudo setcap cap_sys_admin,cap_sys_chroot,cap_dac_override+ep /srv/collabora/coolmount-patch/coolmount.real
Mount the patched directory over /usr/bin:
volumes:
- /srv/collabora/coolmount-patch:/usr/bin
Restart the container and you’re done.
Result
- The broken self-test passes
- mount_jail_tree stays enabled
- Real mount operations succeed through coolmount.real
- No fake behaviour beyond the startup test
- Jails work as intended and performance returns to normal
Example log entry after patch:
exit code: 0
argv: /usr/bin/coolmount -b /opt/cool/systemplate ...
Troubleshooting – How to reproduce and verify the issue yourself
The following commands allow you to:
- Confirm that the error exists on your system (inside a document: Help > Server Audit → “Slow Kit jail setup with copying, cannot bind-mount.”)
- Inspect the failing coolmount calls (exit code 70)
- Verify that the patch works (exit code 0 + real jails mounted)
1. Enter the Collabora container as root
docker exec -u 0 -it collabora bash
2. Inspect binaries
ls -l /usr/bin/coolmount*
getcap /usr/bin/coolmount.real || echo "no caps"
Before patching you will see:
- No wrapper script
- No capabilities set
- Real binary inaccessible for mount operations
3. Trigger the bug
Open any document in Nextcloud, then run:
mount | grep '/opt/cool/child-roots' || echo "no child-root mounts seen"
tail -n 80 /tmp/coolmount.log
If the system is broken, you will see:
- No mounts under /opt/cool/child-roots
- Repeated failures like:
--- exit code: 70 ---
argv: /usr/bin/coolmount -b ...
uid: 1001 user: cool
This confirms that Collabora is falling back to slow copy mode.
4. After applying the patch
Repeat the same commands:
mount | grep '/opt/cool/child-roots' || echo "no child-root mounts seen"
tail -n 80 /tmp/coolmount.log
A working system shows:
- exit code 0 on real mount operations
- Proper jail paths created under /opt/cool/child-roots/…
- No more GUI warnings
- No fallback to copying mode
This proves the jail system is not faked — it is actually working as intended.