Code as an Incus App container

Hi all! I’m trying to run Collabora Code as an application container in Incus, but I’m facing a problem: it doesn’t seem to respond to any request.

In the official documentation the minimal command line to start a new container looks like this:

docker run -t -d -p 127.0.0.1:9980:9980 collabora/code

So, adapting it to Incus, I create the container with:

incus launch docker:collabora/code:latest collabora-container

Then I log inside the container with:

incus exec collabora-container -- su

And then try to connect to the service:

root@collabora-container:/opt/cool# curl -k -vvv https://localhost:9980
*   Trying 127.0.0.1:9980...
* Connected to localhost (127.0.0.1) port 9980 (#0)
* ALPN: offers h2,http/1.1
* TLSv1.3 (OUT), TLS handshake, Client hello (1):

And it gets stuck there… :thinking:

And I see this errors on the container logs:

$ incus console --show-log collabora-container | grep ERR
wsd-00021-00021 2025-07-27 20:32:07.773271 +0000 [ coolwsd ] ERR  enterMountingNS, unshare failed: Permission denied| common/JailUtil.cpp:70
wsd-00021-00021 2025-07-27 20:32:07.773311 +0000 [ coolwsd ] ERR  creating usernamespace for mount user failed.| wsd/COOLWSD.cpp:1272
wsd-00021-00021 2025-07-27 20:32:07.776538 +0000 [ coolwsd ] ERR  Failed to bind-mount [/opt/cool/systemplate] -> [/opt/cool/child-roots/21-bdd1d702/cool_test_mount]| common/JailUtil.cpp:157
wsd-00021-00021 2025-07-27 20:32:07.776567 +0000 [ coolwsd ] ERR  Bind-Mounting fails and will be disabled for this run. To disable permanently set mount_jail_tree config entry in coolwsd.xml to false.| common/JailUtil.cpp:454
frk-00040-00040 2025-07-27 20:32:08.767467 +0000 [ coolforkit-caps ] ERR  Capability cap_sys_chroot is not set for the coolforkit program.| kit/ForKit.cpp:251
frk-00040-00040 2025-07-27 20:32:08.767486 +0000 [ coolforkit-caps ] ERR  Capability cap_fowner is not set for the coolforkit program.| kit/ForKit.cpp:251
frk-00040-00040 2025-07-27 20:32:08.767499 +0000 [ coolforkit-caps ] ERR  Capability cap_chown is not set for the coolforkit program.| kit/ForKit.cpp:251

So, was anybody able to run Collabora Code as an application container in Incus?

Thanks!

Hello @pachulo

I see what’s happening here. You’ve essentially dropped the docker run environment into an Incus/LXD “application container” but Collabora CODE is quite picky about Linux namespaces and capabilities.

From your log:

ERR enterMountingNS, unshare failed: Permission denied
ERR creating usernamespace for mount user failed
ERR Capability cap_sys_chroot is not set
ERR Capability cap_fowner is not set
ERR Capability cap_chown is not set

That’s the root of the problem.

Why it works with Docker but not Incus

  • Docker (or Podman) sets up the container with --cap-add, seccomp tweaks, user namespaces, and AppArmor allowances that Collabora relies on.
  • Incus app containers by default run with a restricted capability set and no unprivileged userns inside. So Collabora fails when trying to set up its jailed child processes (coolforkit, unshare, etc.).

Options you have

  1. Run as a system container instead of application container

    • In Incus you can do:

      incus launch images:debian/12 collabora-code
      incus exec collabora-code -- bash
      # install docker or podman inside, then run collabora/code
      
    • This way the container looks like a lightweight VM and you can run CODE inside with the privileges it expects.

  2. Stick with an application container but adjust security

    • Allow nesting and add missing capabilities:

      incus launch docker:collabora/code:latest collabora-code \
        --config security.nesting=true \
        --config security.syscalls.intercept.mknod=true \
        --config security.syscalls.intercept.mount=true \
        --config security.syscalls.intercept.setxattr=true \
        --config raw.lxc="lxc.cap.keep = sys_chroot chown fowner"
      
    • This gives it the same “extra powers” Docker grants.

    (If you already created the container, you can set those on it with incus config set collabora-code ....)

  3. Disable mount jail in Collabora

    • Inside the container edit /etc/coolwsd/coolwsd.xml and set:

      <mount_jail_tree>false</mount_jail_tree>
      
    • This bypasses the unshare failure, but you’ll still need cap_sys_chroot, cap_fowner, cap_chown for forkit. Otherwise, documents won’t open.

Suggested path

If your goal is simply to get CODE running under Incus reliably, I’d go with option 1 (system container). That avoids chasing all capability quirks. If you really want to use an application container, you’ll need to grant it those capabilities (option 2).

Thanks
Darshan

Thanks for your response, but there seems to be other problems.

I’ve tried your 2nd approach and this is what I got:

$ incus launch docker:collabora/code:latest collabora-code \
  --config security.nesting=true \
  --config security.syscalls.intercept.mknod=true \
  --config security.syscalls.intercept.mount=true \
  --config security.syscalls.intercept.setxattr=true \
  --config raw.lxc="lxc.cap.keep = sys_chroot chown fowner"
$ incus exec collabora-code -- curl -k -vvv https://localhost:9980
*   Trying 127.0.0.1:9980...
* Connected to localhost (127.0.0.1) port 9980 (#0)
* ALPN: offers h2,http/1.1
* TLSv1.3 (OUT), TLS handshake, Client hello (1):

And I’m still seeing these errors on the log:

$ incus console --show-log collabora-code | grep ERR
wsd-00021-00021 2025-08-18 22:22:40.436294 +0000 [ coolwsd ] ERR  enterMountingNS, unshare failed: Permission denied| common/JailUtil.cpp:70
wsd-00021-00021 2025-08-18 22:22:40.436339 +0000 [ coolwsd ] ERR  creating usernamespace for mount user failed.| wsd/COOLWSD.cpp:1272
wsd-00021-00021 2025-08-18 22:22:40.444385 +0000 [ coolwsd ] ERR  Failed to bind-mount [/opt/cool/systemplate] -> [/opt/cool/child-roots/21-a64d9fa7/cool_test_mount]| common/JailUtil.cpp:157
wsd-00021-00021 2025-08-18 22:22:40.444464 +0000 [ coolwsd ] ERR  Bind-Mounting fails and will be disabled for this run. To disable permanently set mount_jail_tree config entry in coolwsd.xml to false.| common/JailUtil.cpp:454
frk-00042-00042 2025-08-18 22:22:41.463179 +0000 [ coolforkit-caps ] ERR  Capability cap_sys_chroot is not set for the coolforkit program.| kit/ForKit.cpp:251
frk-00042-00042 2025-08-18 22:22:41.463192 +0000 [ coolforkit-caps ] ERR  Capability cap_fowner is not set for the coolforkit program.| kit/ForKit.cpp:251
frk-00042-00042 2025-08-18 22:22:41.463197 +0000 [ coolforkit-caps ] ERR  Capability cap_chown is not set for the coolforkit program.| kit/ForKit.cpp:251

By the way, I’m trying this on an Oracle Cloud ARM64 instance, if that matters:

$ uname -a
Linux arm64-server 6.14.0-1011-oracle #11~24.04.1-Ubuntu SMP Mon Aug  4 18:41:59 UTC 2025 aarch64 aarch64 aarch64 GNU/Linux

Hello @pachulo

From your logs:

enterMountingNS, unshare failed: Permission denied
creating usernamespace for mount user failed
Capability cap_sys_chroot is not set for the coolforkit program
...
Bind-Mounting fails and will be disabled for this run

This tells us two things:

  1. Incus container is not granting the kernel features Collabora expects
    Collabora tries to unshare() into new mount/user namespaces and do bind-mounts into /opt/cool/child-roots/…. By default, Incus blocks parts of this unless you explicitly relax security.
  2. Capabilities missing inside the container
    coolforkit needs CAP_SYS_CHROOT, CAP_FOWNER, and CAP_CHOWN. Your raw.lxc currently has a cap.keep line, but it’s not actually giving the binary the capabilities — it just prevents dropping them if they exist. Since you’re using a Docker image inside Incus, capabilities aren’t being passed through.