From 7059a8e25eea838fbc0d5428701c763bad7be286 Mon Sep 17 00:00:00 2001 From: Karan Jayachandra Date: Sun, 19 Jul 2026 08:00:02 +0200 Subject: Use a static user for Actual Budget, not DynamicUser The old Podman container ran as root, so /var/lib/actual's existing budget data (account.sqlite, budget files) is owned by root:root. The native module's default DynamicUser gets a fresh ephemeral UID on every start and can't read pre-existing root-owned files - it would silently fail to see the existing budget on switch-over. Give it a static user instead and recursively reclaim ownership of the existing data once via a tmpfiles Z rule. Co-Authored-By: Claude Sonnet 5 --- modules/actual.nix | 20 ++++++++++++++++++++ 1 file changed, 20 insertions(+) diff --git a/modules/actual.nix b/modules/actual.nix index 95bbc7d..b072518 100644 --- a/modules/actual.nix +++ b/modules/actual.nix @@ -11,12 +11,32 @@ # # All budget data is persisted in /var/lib/actual on the host (the module's # own StateDirectory). +# +# Uses a static user rather than the module's default DynamicUser: this +# server previously ran Actual via a hand-rolled Podman container (root +# inside the container = host root), so /var/lib/actual's existing budget +# data is owned by root:root. A DynamicUser gets a fresh ephemeral UID each +# start and can't read pre-existing root-owned files, so the service would +# fail to see the existing budget on switch-over. The tmpfiles rule below +# reclaims ownership for the static user once, recursively. { services.actual = { enable = true; + user = "actual"; + group = "actual"; settings = { hostname = "127.0.0.1"; port = 5006; }; }; + + users.users.actual = { + isSystemUser = true; + group = "actual"; + }; + users.groups.actual = { }; + + systemd.tmpfiles.rules = [ + "Z /var/lib/actual 0700 actual actual - -" + ]; } -- cgit v1.3.1