Document that secretFile/adminAccount.passwordFile are read as cfg.user

hortusfox-setup reads both files as cfg.user, not root. Pointing either
at an agenix/sops-nix secret without setting its owner/group to match
cfg.user/cfg.group fails the service with a permission error rather
than anything obviously related -- note it on both options.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
This commit is contained in:
2026-09-28 13:56:51 -04:00
co-authored by Claude Sonnet 5
parent 6f16735747
commit e210e344c8
2 changed files with 10 additions and 4 deletions
+2 -2
View File
@@ -67,9 +67,9 @@ and a `services.hortusfox-web` NixOS module that wires the built package into a
| `user` / `group` | string | `"hortusfox"` | System user/group the app and its phpfpm pool run as. | | `user` / `group` | string | `"hortusfox"` | System user/group the app and its phpfpm pool run as. |
| `timezone` | string | `"UTC"` | App timezone (`APP_TIMEZONE`). | | `timezone` | string | `"UTC"` | App timezone (`APP_TIMEZONE`). |
| `database.name` | string | `"hortusfox"` | MariaDB database name. | | `database.name` | string | `"hortusfox"` | MariaDB database name. |
| `secretFile` | null or path | `null` | File of `KEY=VALUE` lines (`APP_KEY`, `SMTP_PASSWORD`, API keys, ...) appended verbatim onto the generated `.env` at runtime — not parsed, so it can carry arbitrary keys. Keep it out of the Nix store in production (agenix/sops-nix); a store path is fine for throwaway test configs. | | `secretFile` | null or path | `null` | File of `KEY=VALUE` lines (`APP_KEY`, `SMTP_PASSWORD`, API keys, ...) appended verbatim onto the generated `.env` at runtime — not parsed, so it can carry arbitrary keys. Keep it out of the Nix store in production (agenix/sops-nix); a store path is fine for throwaway test configs. Read by `hortusfox-setup`, which runs as the module's system user, not root — make sure its owner/group lets that user read it. |
| `backupMaxAge` | null or string | `"1d"` | How long HortusFox's own export/auto-backup zips (`public/backup`, systemd-tmpfiles "age" syntax, e.g. `"1d"`, `"12h"`) are kept before auto-deletion. HortusFox names these with a fully predictable `hf_backup_<timestamp>.zip` pattern and serves them from the public webroot without ever cleaning them up itself, so anyone who knows or guesses the timestamp can otherwise download a full data export indefinitely. `null` disables cleanup entirely (not recommended for internet-facing deployments). | | `backupMaxAge` | null or string | `"1d"` | How long HortusFox's own export/auto-backup zips (`public/backup`, systemd-tmpfiles "age" syntax, e.g. `"1d"`, `"12h"`) are kept before auto-deletion. HortusFox names these with a fully predictable `hf_backup_<timestamp>.zip` pattern and serves them from the public webroot without ever cleaning them up itself, so anyone who knows or guesses the timestamp can otherwise download a full data export indefinitely. `null` disables cleanup entirely (not recommended for internet-facing deployments). |
| `adminAccount.passwordFile` | null or path | `null` | Plaintext password file for a seeded initial admin account. HortusFox has no CLI/seed hook of its own and its only "create user" flow lives behind the admin panel, so without this a fresh deployment has no way to log in at all. Only takes effect on first boot; changing it later has no effect on an existing account. | | `adminAccount.passwordFile` | null or path | `null` | Plaintext password file for a seeded initial admin account. HortusFox has no CLI/seed hook of its own and its only "create user" flow lives behind the admin panel, so without this a fresh deployment has no way to log in at all. Only takes effect on first boot; changing it later has no effect on an existing account. Read by `hortusfox-setup` under the same non-root user as `secretFile` above. |
| `adminAccount.username` | string | `"admin"` | Name for the seeded admin account — purely a display name, since HortusFox logs in by email rather than this field. | | `adminAccount.username` | string | `"admin"` | Name for the seeded admin account — purely a display name, since HortusFox logs in by email rather than this field. |
| `adminAccount.email` | string | `"admin@${domain}"` | Email for the seeded admin account. The default is just a guess at a real mailbox — set it to an address you actually control if you intend to use HortusFox's "Restore password" flow, which emails it. | | `adminAccount.email` | string | `"admin@${domain}"` | Email for the seeded admin account. The default is just a guess at a real mailbox — set it to an address you actually control if you intend to use HortusFox's "Restore password" flow, which emails it. |
| `settings` | attrs of str/int/bool | `{ }` | Extra/overriding `.env` entries, merged over the module's generated defaults (`settings` always wins). Note `php asatru` (used for migrations) only runs when `APP_DEBUG` is true, so migrations silently no-op unless it's set here or via `secretFile`. | | `settings` | attrs of str/int/bool | `{ }` | Extra/overriding `.env` entries, merged over the module's generated defaults (`settings` always wins). Note `php asatru` (used for migrations) only runs when `APP_DEBUG` is true, so migrations silently no-op unless it's set here or via `secretFile`. |
+8 -2
View File
@@ -229,7 +229,11 @@ in {
File with secret KEY=VALUE lines (APP_KEY, SMTP_PASSWORD, API keys, File with secret KEY=VALUE lines (APP_KEY, SMTP_PASSWORD, API keys,
...) appended verbatim to the generated .env at runtime. Keep it out ...) appended verbatim to the generated .env at runtime. Keep it out
of the Nix store in production (e.g. agenix/sops-nix); a store path of the Nix store in production (e.g. agenix/sops-nix); a store path
is fine for throwaway test configs. is fine for throwaway test configs. Read by hortusfox-setup, which
runs as cfg.user rather than root -- if you point this at an
agenix/sops-nix secret, make sure its owner/group is set to
cfg.user/cfg.group (or make it world-readable), or the service fails
with a permission error.
''; '';
}; };
@@ -261,7 +265,9 @@ in {
a fresh deployment has no way to log in at all. Only used on first a fresh deployment has no way to log in at all. Only used on first
boot (guarded by the same stateDir/.installed marker as boot (guarded by the same stateDir/.installed marker as
migrate:fresh); changing it afterwards has no effect on an migrate:fresh); changing it afterwards has no effect on an
existing account. existing account. Read by hortusfox-setup, which runs as cfg.user
rather than root -- as with secretFile, make sure this file's
owner/group lets cfg.user read it.
Seeds a user (name set via adminAccount.username, email via Seeds a user (name set via adminAccount.username, email via
adminAccount.email), bcrypt-hashed via adminAccount.email), bcrypt-hashed via