infra: mirror LAN dev secrets under $HOME for snap-confined Docker #85

Merged
admin_emi merged 2 commits from fix/lan-dev-secrets-snap-confinement into dev 2026-07-25 07:16:10 +00:00
Owner

Docker on the LAN box is the snap package, sandboxed to $HOME (plus a short allowlist) -- it cannot see /etc/thermograph.env at all, so env_file: /etc/thermograph.env silently loads nothing for every container there regardless of how correctly the vault renders. Confirmed directly: docker run --env-file /etc/thermograph.env fails with no such file or directory on a file the shell reads fine; the identical content under $HOME loads correctly via the same flag.

This is why thermograph-dev-daemon-1 kept crash-looping on a missing THERMOGRAPH_AUTH_SECRET even after PR #77 correctly added it to dev.yaml and PR #84 fixed the runner's PATH so sops could render it at all -- the render was correct, the container just structurally could not see the result.

What this does

  • render-secrets.sh: opt-in second write via THERMOGRAPH_SECRETS_ENV_FILE_MIRROR -- unset (prod/beta) is a no-op.
  • deploy-dev.sh: sets it to $APP_DIR/infra/deploy/dev-secrets.env (gitignored, re-rendered every deploy).
  • docker-compose.dev.yml: adds that path as a second env_file entry on backend/daemon/lake -- compose appends env_file lists across overlays (last-wins on duplicate keys), so this is additive; prod/beta never set the mirror var and only ever get the base /etc/thermograph.env entry.

Verified

docker run --env-file ~/thermograph-dev/infra/deploy/dev-secrets.env alpine env correctly lists THERMOGRAPH_AUTH_SECRET and every other rendered key. (The compose-level wiring needs re-verifying post-merge -- an earlier hand-edit of the live checkout got wiped by deploy.sh's own git reset --hard, a reminder that this really does need to land through git, not a live edit.)

No tests -- shell/compose provisioning, dev-only behavior change.

Docker on the LAN box is the snap package, sandboxed to `$HOME` (plus a short allowlist) -- it cannot see `/etc/thermograph.env` at all, so `env_file: /etc/thermograph.env` silently loads nothing for every container there regardless of how correctly the vault renders. Confirmed directly: `docker run --env-file /etc/thermograph.env` fails with `no such file or directory` on a file the shell reads fine; the identical content under `$HOME` loads correctly via the same flag. This is why `thermograph-dev-daemon-1` kept crash-looping on a missing `THERMOGRAPH_AUTH_SECRET` even after PR #77 correctly added it to `dev.yaml` and PR #84 fixed the runner's PATH so `sops` could render it at all -- the render was correct, the container just structurally could not see the result. ## What this does - `render-secrets.sh`: opt-in second write via `THERMOGRAPH_SECRETS_ENV_FILE_MIRROR` -- unset (prod/beta) is a no-op. - `deploy-dev.sh`: sets it to `$APP_DIR/infra/deploy/dev-secrets.env` (gitignored, re-rendered every deploy). - `docker-compose.dev.yml`: adds that path as a second `env_file` entry on `backend`/`daemon`/`lake` -- compose appends `env_file` lists across overlays (last-wins on duplicate keys), so this is additive; prod/beta never set the mirror var and only ever get the base `/etc/thermograph.env` entry. ## Verified `docker run --env-file ~/thermograph-dev/infra/deploy/dev-secrets.env alpine env` correctly lists `THERMOGRAPH_AUTH_SECRET` and every other rendered key. (The compose-level wiring needs re-verifying post-merge -- an earlier hand-edit of the live checkout got wiped by deploy.sh's own `git reset --hard`, a reminder that this really does need to land through git, not a live edit.) No tests -- shell/compose provisioning, dev-only behavior change.
admin_emi added 1 commit 2026-07-25 07:09:06 +00:00
infra: mirror LAN dev's rendered secrets under $HOME for snap-confined Docker
Some checks failed
PR build (required check) / changes (pull_request) Successful in 26s
secrets-guard / encrypted (pull_request) Successful in 10s
shell-lint / shellcheck (pull_request) Failing after 14s
PR build (required check) / validate-observability (pull_request) Successful in 1m5s
PR build (required check) / build-frontend (pull_request) Successful in 3m47s
PR build (required check) / build-backend (pull_request) Successful in 4m44s
PR build (required check) / gate (pull_request) Successful in 6s
73cd6b7aae
Docker on the LAN box is the snap package, sandboxed to $HOME (plus a
short allowlist) -- it can't see /etc/thermograph.env at all, so
env_file: /etc/thermograph.env silently loads nothing for every
container there, no matter how correctly the vault renders. Confirmed
directly: `docker run --env-file /etc/thermograph.env` fails with
"no such file or directory" on a file the shell reads fine; the same
file under $HOME loads correctly.

render-secrets.sh gains an opt-in second write
(THERMOGRAPH_SECRETS_ENV_FILE_MIRROR), deploy-dev.sh points it at
infra/deploy/dev-secrets.env (gitignored, re-rendered every deploy),
and docker-compose.dev.yml adds it as a second env_file entry for
backend/daemon/lake -- compose appends env_file lists across overlays,
so this is additive and prod/beta (which never set the mirror var)
are unaffected.
admin_emi added 1 commit 2026-07-25 07:12:11 +00:00
render-secrets.sh: fix SC2015 in the mirror-write guard
All checks were successful
PR build (required check) / changes (pull_request) Successful in 21s
secrets-guard / encrypted (pull_request) Successful in 26s
shell-lint / shellcheck (pull_request) Successful in 23s
PR build (required check) / validate-observability (pull_request) Successful in 48s
PR build (required check) / build-frontend (pull_request) Successful in 2m14s
PR build (required check) / build-backend (pull_request) Successful in 2m46s
PR build (required check) / gate (pull_request) Successful in 2s
40d3b5f5dc
A && B || C isn't if-then-else -- C can run when A is true but B
fails too. Use an explicit if/else so an mkdir success + install
failure is still caught.
admin_emi merged commit 9b6b12a5da into dev 2026-07-25 07:16:10 +00:00
admin_emi deleted branch fix/lan-dev-secrets-snap-confinement 2026-07-25 07:16:10 +00:00
Sign in to join this conversation.
No reviewers
No milestone
No project
No assignees
1 participant
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: Jinemi/thermograph#85
No description provided.