#30 - Add the Nextcloud desktop client with auto-start and a KWallet keyring #31

Merged
GuillaumeHemmen merged 1 commit from 30-nextcloud-desktop-client into master 2026-10-12 15:35:49 +00:00
Member

What

The coder-xfce-vnc variant now ships the Nextcloud desktop client (34.0.5, from Nextcloud's official PPA). It starts automatically with the desktop and stays logged in across workspace restarts. Its login is kept in KWallet, which is created with an empty password and unlocked silently at session start. Nothing GNOME is involved.

Why

See #30. The client stores its app password in the system keyring and compiles out qtkeychain's plain-file fallback (keychainchunk.h: "We don't support insecure fallback"). The image has no keyring, so without one the client would ask for a new login after every restart. JetBrains Toolbox doesn't have this problem because it falls back to its own .securestorage file.

Changes

  • Dockerfile (coder-xfce-vnc stage):
    • New RUN step that adds the nextcloud-devs/client PPA, using the same keyring + sources.list.d pattern as the other repos:
      • the Launchpad signing-key fingerprint 1FCD77DD…AD3DD469 is asserted before the key is trusted;
      • the suite comes from /etc/os-release instead of a hard-coded noble.
    • It installs:
      • nextcloud-desktop;
      • libkf5wallet-bin (kwalletd5);
      • libqca-qt5-2-plugins: the QCA OpenSSL plugin KWallet's Secret Service needs. Without it, every write fails with createDLGroup failed: maybe libqca-ossl is missing.
    • It then asserts the binary, daemon, D-Bus activation and plugin paths.
    • ENV QTWEBENGINE_DISABLE_SANDBOX=1 and QTWEBENGINE_CHROMIUM_FLAGS=--disable-dev-shm-usage. The client embeds Qt WebEngine, which hits the same pod limits as the Electron apps but ignores ELECTRON_DISABLE_SANDBOX. These are ENV rather than a wrapper, because the client writes its own auto-start entry pointing at /usr/bin/nextcloud.
    • COPY of the new kwallet-unlock script.
  • scripts/kwallet-unlock.sh (new):
    • Derives the wallet key exactly as KWallet does: PBKDF2-HMAC-SHA512 of "" over the 56-byte salt, 50000 rounds, 56 bytes.
    • Calls kwalletd's pamOpen, the same call pam_kwallet5 makes on a KDE login. That creates the wallet on first run and opens it with no dialog.
    • Checks success with isOpen, since pamOpen returns nothing over D-Bus.
    • Leaves a wallet with a real password alone, and never fails the session.
  • scripts/start-xfce-vnc.sh: the generated xstartup runs kwallet-unlock, guarded by command -v, inside dbus-run-session before startxfce4. The unlock therefore happens before the client auto-starts.
  • scripts/coder-init-desktop.sh: writes ~/.config/autostart/Nextcloud.desktop once per home, with a marker file.
    • It's the same file the client's Launch on system startup toggle writes and deletes, so that toggle stays authoritative, and a user who turns it off stays off.
    • A system-wide /etc/xdg/autostart entry was ruled out: the toggle only looks in ~/.config/autostart, so it could never turn that one off.
  • README.md:
    • feature list entries;
    • new Nextcloud Desktop Client section: first use, auto-start, why KWallet, the security trade-off, how to use a real password, the effect on other apps, and the Qt WebEngine variables;
    • a coder-init-desktop bullet;
    • persisted-state table rows;
    • Version Information.

Things to weigh in review

  • Image size: +549 MB on the desktop variant, measured with df around the real RUN step. That's mostly Qt 6 + Qt WebEngine for the client; KWallet is about 81 MB of it. It's more than the "200–350 MB + 81" I estimated before measuring.
  • The Secret Service is now available to every app in the session. I first planned to disable it and point qtkeychain at KWallet directly. But Ubuntu's qtkeychain 0.14.2 has no QTKEYCHAIN_BACKEND override (that arrived in 0.15) and always picks libsecret on XFCE, so Nextcloud can only reach KWallet this way. As a result, apps that look for a keyring on XFCE may start keeping their secrets in KWallet. That includes Electron apps through Chromium's os_crypt, such as Claude Desktop. Data they encrypted before (Chromium's v10 format) should stay readable. Not verified: I couldn't log in to Claude Desktop in a test pod. Freelens started normally and wrote nothing to the wallet.
  • Empty password: this is the same protection level as Toolbox's .securestorage, as agreed. The README explains how to set a real one.

Verification

All checks ran in throwaway pods from coder-xfce-vnc-latest, using the actual scripts from this branch and a throwaway Nextcloud 35.0.1 server in the cluster (all deleted afterwards):

Check Result
New RUN step, extracted from the Dockerfile by script, run as root in a fresh pod exit 0 in 19.5 s, no W:/E: lines, key fingerprint matched, nextcloud-desktop 34.0.5, libkf5wallet-bin 5.115.0, libqca-qt5-2-plugins 2.3.8
coder-init-desktop on a fresh home writes ~/.config/autostart/Nextcloud.desktop + marker
start-xfce-vnc session 1 kwallet-unlock: kdewallet is open. before XFCE starts; xfce4-session, kwalletd5 and nextcloud --background (auto-started) running
Account added with the client's --serverurl/--userid/--apppassword initial sync of the server's default files to ~/Nextcloud; password written to KWallet (Secret Service folder holds Nextcloud, Nextcloud__0_)
Same, before the fix Error while writing password "The name org.freedesktop.secrets was not provided by any .service files" (Secret Service disabled), then createDLGroup failed: maybe libqca-ossl is missing (plugin missing). Both are fixed by this PR
Full session restart (VNC, XFCE, kwalletd killed and restarted) client auto-started, reconnected with no prompt, and synced down a file uploaded on the server after the restart (HTTP 201 upload → file present locally)
Dialogs none: the window list held only the panel, the desktop and the app under test; no wallet or password windows
Tray Nextcloud's 22×22 icon embedded in the XFCE panel's system tray
Wallet with a real password kwallet-unlock leaves it locked (isOpen → false), exits 0 in 0.09 s
kwalletd unable to start kwallet-unlock logs and exits 0, so the session isn't blocked
Freelens with the Secret Service available starts normally, no prompt, nothing written to the wallet
shellcheck on the three scripts clean

Not verified:

  • the interactive Login Flow v2 through Firefox (I used the client's command-line account setup instead);
  • arm64 (the plugin assertion covers both library paths);
  • the full kaniko image build, which the branch push has started in docker-dev.

Closes #30

🤖 Generated with Claude Code

## What The `coder-xfce-vnc` variant now ships the **Nextcloud desktop client** (34.0.5, from Nextcloud's official PPA). It **starts automatically** with the desktop and **stays logged in across workspace restarts**. Its login is kept in **KWallet**, which is created with an empty password and unlocked silently at session start. Nothing GNOME is involved. ## Why See #30. The client stores its app password in the system keyring and compiles out qtkeychain's plain-file fallback (`keychainchunk.h`: "We don't support insecure fallback"). The image has no keyring, so without one the client would ask for a new login after every restart. JetBrains Toolbox doesn't have this problem because it falls back to its own `.securestorage` file. ## Changes - **`Dockerfile` (`coder-xfce-vnc` stage):** - New `RUN` step that adds the `nextcloud-devs/client` PPA, using the same keyring + `sources.list.d` pattern as the other repos: - the Launchpad signing-key fingerprint `1FCD77DD…AD3DD469` is asserted before the key is trusted; - the suite comes from `/etc/os-release` instead of a hard-coded `noble`. - It installs: - `nextcloud-desktop`; - `libkf5wallet-bin` (`kwalletd5`); - `libqca-qt5-2-plugins`: the QCA OpenSSL plugin KWallet's Secret Service needs. Without it, every write fails with `createDLGroup failed: maybe libqca-ossl is missing`. - It then asserts the binary, daemon, D-Bus activation and plugin paths. - `ENV QTWEBENGINE_DISABLE_SANDBOX=1` and `QTWEBENGINE_CHROMIUM_FLAGS=--disable-dev-shm-usage`. The client embeds Qt WebEngine, which hits the same pod limits as the Electron apps but ignores `ELECTRON_DISABLE_SANDBOX`. These are ENV rather than a wrapper, because the client writes its own auto-start entry pointing at `/usr/bin/nextcloud`. - `COPY` of the new `kwallet-unlock` script. - **`scripts/kwallet-unlock.sh` (new):** - Derives the wallet key exactly as KWallet does: PBKDF2-HMAC-SHA512 of `""` over the 56-byte salt, 50000 rounds, 56 bytes. - Calls kwalletd's `pamOpen`, the same call `pam_kwallet5` makes on a KDE login. That creates the wallet on first run and opens it with no dialog. - Checks success with `isOpen`, since `pamOpen` returns nothing over D-Bus. - Leaves a wallet with a real password alone, and never fails the session. - **`scripts/start-xfce-vnc.sh`:** the generated `xstartup` runs `kwallet-unlock`, guarded by `command -v`, inside `dbus-run-session` before `startxfce4`. The unlock therefore happens before the client auto-starts. - **`scripts/coder-init-desktop.sh`:** writes `~/.config/autostart/Nextcloud.desktop` once per home, with a marker file. - It's the same file the client's *Launch on system startup* toggle writes and deletes, so that toggle stays authoritative, and a user who turns it off stays off. - A system-wide `/etc/xdg/autostart` entry was ruled out: the toggle only looks in `~/.config/autostart`, so it could never turn that one off. - **`README.md`:** - feature list entries; - new **Nextcloud Desktop Client** section: first use, auto-start, why KWallet, the security trade-off, how to use a real password, the effect on other apps, and the Qt WebEngine variables; - a `coder-init-desktop` bullet; - persisted-state table rows; - Version Information. ## Things to weigh in review - **Image size: +549 MB** on the desktop variant, measured with `df` around the real `RUN` step. That's mostly Qt 6 + Qt WebEngine for the client; KWallet is about 81 MB of it. It's more than the "200–350 MB + 81" I estimated before measuring. - **The Secret Service is now available to every app in the session.** I first planned to disable it and point qtkeychain at KWallet directly. But Ubuntu's qtkeychain 0.14.2 has no `QTKEYCHAIN_BACKEND` override (that arrived in 0.15) and always picks libsecret on XFCE, so Nextcloud can only reach KWallet this way. As a result, apps that look for a keyring on XFCE may start keeping their secrets in KWallet. That includes Electron apps through Chromium's `os_crypt`, such as Claude Desktop. Data they encrypted before (Chromium's `v10` format) should stay readable. **Not verified:** I couldn't log in to Claude Desktop in a test pod. Freelens started normally and wrote nothing to the wallet. - **Empty password:** this is the same protection level as Toolbox's `.securestorage`, as agreed. The README explains how to set a real one. ## Verification All checks ran in throwaway pods from `coder-xfce-vnc-latest`, using the actual scripts from this branch and a throwaway Nextcloud 35.0.1 server in the cluster (all deleted afterwards): | Check | Result | |---|---| | New `RUN` step, extracted from the Dockerfile by script, run as root in a fresh pod | **exit 0 in 19.5 s**, no `W:`/`E:` lines, key fingerprint matched, `nextcloud-desktop 34.0.5`, `libkf5wallet-bin 5.115.0`, `libqca-qt5-2-plugins 2.3.8` | | `coder-init-desktop` on a fresh home | writes `~/.config/autostart/Nextcloud.desktop` + marker | | `start-xfce-vnc` session 1 | `kwallet-unlock: kdewallet is open.` before XFCE starts; `xfce4-session`, `kwalletd5` and `nextcloud --background` (auto-started) running | | Account added with the client's `--serverurl/--userid/--apppassword` | initial sync of the server's default files to `~/Nextcloud`; password written to KWallet (`Secret Service` folder holds `Nextcloud`, `Nextcloud__0_`) | | Same, **before** the fix | `Error while writing password "The name org.freedesktop.secrets was not provided by any .service files"` (Secret Service disabled), then `createDLGroup failed: maybe libqca-ossl is missing` (plugin missing). Both are fixed by this PR | | **Full session restart** (VNC, XFCE, kwalletd killed and restarted) | client auto-started, reconnected with no prompt, and synced down a file uploaded on the server **after** the restart (HTTP 201 upload → file present locally) | | Dialogs | none: the window list held only the panel, the desktop and the app under test; no wallet or password windows | | Tray | Nextcloud's 22×22 icon embedded in the XFCE panel's system tray | | Wallet with a real password | `kwallet-unlock` leaves it locked (`isOpen` → false), exits 0 in 0.09 s | | kwalletd unable to start | `kwallet-unlock` logs and exits 0, so the session isn't blocked | | Freelens with the Secret Service available | starts normally, no prompt, nothing written to the wallet | | `shellcheck` on the three scripts | clean | **Not verified:** - the interactive Login Flow v2 through Firefox (I used the client's command-line account setup instead); - arm64 (the plugin assertion covers both library paths); - the full kaniko image build, which the branch push has started in `docker-dev`. Closes #30 🤖 Generated with [Claude Code](https://claude.com/claude-code)
#30 - Add the Nextcloud desktop client with auto-start and a KWallet keyring
All checks were successful
/ docker-dev-ci (push) Successful in 4m11s
/ docker-dev-coder (push) Successful in 4m54s
/ docker-dev-coder-xfce-vnc (push) Successful in 11m7s
a6c2a56923
Install nextcloud-desktop from Nextcloud's official PPA in the
coder-xfce-vnc stage, with KWallet (libkf5wallet-bin) as the keyring that
keeps its login across workspace restarts:

- kwallet-unlock creates the wallet with an empty password on first run
  and unlocks it at every session start through kwalletd's pamOpen, the
  same call pam_kwallet5 makes. start-xfce-vnc's xstartup runs it inside
  the session bus before XFCE starts.
- The client reaches KWallet through its Secret Service interface,
  because Ubuntu's qtkeychain 0.14 always picks libsecret on XFCE. That
  interface needs libqca-qt5-2-plugins.
- coder-init-desktop turns on auto-start once per home, by writing the
  same entry the client's own toggle manages.
- QTWEBENGINE_DISABLE_SANDBOX / QTWEBENGINE_CHROMIUM_FLAGS cover the
  embedded Qt WebEngine, which hits the same pod limits as Electron.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
GuillaumeHemmen deleted branch 30-nextcloud-desktop-client 2026-10-12 15:35:49 +00:00
Sign in to join this conversation.
No reviewers
No labels
No milestone
No project
No assignees
2 participants
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set.

Reference
actions/sindri!31
No description provided.