Stand up postgresql on chicken #4
Loading…
Add table
Add a link
Reference in a new issue
No description provided.
Delete branch "%!s()"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
I'm going to move postgresql out of the kubernetes cluster and on to bare metal. As the cluster is intended to be rebuilt in the near future, it's a good idea to move it entirely out of systems that the cluster currently touches. Therefore, we'll put it on chicken. It has enough storage for the small postgres database I need.
A couple challenges:
Good plan to move Postgres off-k8s. Here are some findings from nixpkgs and nixos.wiki that might help:
1. Multi-tenant PostgreSQL in NixOS
nixpkgs already has
services.postgresqlwith full multi-database/multi-user support. Each service tenant gets its own database + role with limited privileges. Typical pattern:2. Injecting credentials into Kubernetes
You have several options (ranked by simplicity):
kubectl create secretfrom Postgres roles)kubernetes.addonManager.bootstrapAddonsmentioned in your issue is actually for K8s API server auth, not for secret injection — skip this path3. Restic backups with pg_dump
nixpkgs provides
services.postgresql.pg_dumpallwhich integrates withservices.restic.backups:See nixos.wiki/restic and nixos.wiki/postgresql for the
backupCommand+postBackupCommanddance.4. Disk space for backups
Chicken's
/volume needs to accommodate both data and restic repo. Consider using an external drive orrestic's--excludeflag to ignore very large non-critical databases.5. Network exposure
Since this is bare metal, expose PostgreSQL only on the internal network (e.g.,
10.0.0.0/24) inservices.postgresql.listenAddresses. Use SSH tunneling or WireGuard for cross-network access.Happy to help draft the Nix config once you have a preferred backup/secret injection strategy. Let me know which direction you take.
@hermes-bot
kubectl create secret ...from chicken at startup to inject credentials when it starts. Would make key rotation automatic too.Give me an initial implementation of this and push a PR for it
@hermes-bot Please implement this and push a PR for it
@rpickler Implemented and pushed: PR #6 (
postgres-chickenbranch).Answering your points:
rest:http://…@pi4:8000/chicken-postgresusing the existingrestic-passphraseSOPS secret, withbackupPrepareCommanddoing per-tenantpg_dump -Fc+pg_dumpall --globals-only(nixpkgs'services.restic.backupssupports this natively — that's the "anything already available in nixpkgs" answer from the issue).192.168.97.0/24and10.0.0.0/24(configurable viaallowedSourceNetworks).pickler-postgres-setup.serviceensures role/db + password from SOPS at startup,pickler-postgres-k8s-sync.servicepushes per-namespace Secrets viakubectl, and a reconcile timer (12h) makes rotation automatic without waiting for a deploy. Needs a scoped kubeconfig in SOPS to activate (pickler.postgres.kubernetes.kubeconfigSecret); everything else works without it.Read the PR body for the tenant onboarding flow (SOPS key
postgres-<tenant>-password+ onetenants.<name>entry) and the 4 follow-ups I deliberately left out. This revision has nonix flake checkbehind it — review especially the generated SQL/shell insetupScript.We've struggled mightily on peer-programming this one. Can you asses where we are and check if there is anything else that needs to be done. With your nix tooling, please ensure that chicken evaluates cleanly.
Assessment (2026-10-21)
The end-state this issue asked for is implemented on PR #6 and chicken now evaluates cleanly. Verified with a real Nix toolchain (nix 2.34.9 against the flake-pinned nixpkgs):
nix eval .#nixosConfigurations.chicken.config.system.build.toplevel.drvPath→ exit 0 onpostgres-chicken(full system config evaluates; all module assertions pass).mainevaluates clean as well (baseline).pickler-postgres-setup+pickler-postgres-reconcileunits,restic-backups-postgres(daily 02:30, Persistent,initialize = true), sops secretspostgres-authentik/restic-passphrase, templatesauthentik-conn/postgres-restic-repository, 5432 open on the firewall, and pg_hba = unix peer locally + scram-sha-256 restricted to192.168.97.0/24and10.0.0.0/24.pickler-postgres-k8s-syncis correctly absent — Kubernetes injection stays dormant untilpickler.postgres.kubernetes.kubeconfigSecretis set, as designed.Fixed today (
d31c05c):systemctlExewaslib.getExe pkgs.systemd, which resolves tobin/systemd— the init binary — because the systemd package has nometa.mainProgramandgetExefalls back to the package name. Consequence: the activation guardsystemctl is-active postgresqlwould never have succeeded andpickler-postgres-reconcile.servicewould exec the wrong binary, so credential reconcile would silently never run. Nowlib.getExe' pkgs.systemd "systemctl"; re-evaluated clean (the eval warning that exposed it is gone) and the activation script verified to execbin/systemctl.All 4 REQUEST_CHANGES findings on PR #6 are fixed on the branch (
c0bc771, Oct 16). The review is still formally REQUEST_CHANGES, so the PR is ready for a re-review since it now carries a clean full-system eval.What's left (none of it eval-blocking)
.data['ca.crt']/.data.token(kubectl config set-cluster/set-credentials/set-context), add it tomodules/secrets.yamlaspostgresql-kubeconfig: |, and setpickler.postgres.kubernetes.kubeconfigSecret = "postgresql-kubeconfig"inhosts/chicken.nix. One Role+RoleBinding per tenant namespace.nixos-rebuild switchon chicken additionally exercises runtime bits eval can't: reaching the REST server on pi4 (initialize = truecreates thechicken-postgresrepo on first backup) and the authentik tenant password you put in SOPS.authentik-postgresSecret (keyspassword/uri) lands in theauthentiknamespace, point authentik atchicken.lan:5432and retire the in-cluster postgres. Each later tenant = SOPS entry + onetenants.<name>block.system.stateVersionis unset for chicken (defaults to 26.05; warning is benign and predates the PR). Worth pinning to whatever chicken was installed with when convenient — same situation for the other hosts that skipmodules/common.nix.Re-verified today (2026-10-21) after this card re-fired — nothing in the assessment above changed, and one gap it left is now closed:
nix eval .#nixosConfigurations.chicken.config.system.build.toplevel.drvPath→ exit 0 onpostgres-chicken@d31c05c, onmain@e0957de, and on a test merge of the two — so PR #6's true end-state evaluates cleanly even thoughmainmoved ahead since the branch was cut (no conflicts either;merge-treeclean, PR reportsmergeable). The earlier run only pinned the branch's own nixpkgs (20261013); the merged tree carriesmain's newer pin (20261019) and still evaluates with only the benignstateVersionwarning.mainahead of the branch is purely additive on this PR's files (e.g. the neovim #32 merge), so no rebase needed before review — GitHub/Forgejo will handle it at merge.Nothing eval-blocking remains on my side. Open items are all yours (from the list above): kubeconfig for
pickler-postgres-k8s-syncwhen you're ready to activate credential injection, firstnixos-rebuild switchon chicken, then re-target authentik. PR #6 is ready for re-review — the 4 REQUEST_CHANGES findings are fixed on the branch and awaiting an approving review.