This commit is contained in:
mjallen18
2026-03-20 18:24:51 -05:00
parent 27790713be
commit 6f77344d42
13 changed files with 350 additions and 365 deletions

View File

@@ -346,7 +346,7 @@ These are not workarounds but known incomplete configurations:
|------|------|-------------|
| `systems/x86_64-linux/jallen-nas/sops.nix` | 89, 113 | Collabora and MariaDB secrets not configured |
| `systems/x86_64-linux/jallen-nas/apps.nix` | 47 | Authentik environment secrets file not wired up |
| `modules/nixos/services/sparky-fitness/default.nix` | 36, 72 | DB passwords not yet moved to SOPS |
| `modules/nixos/services/sparky-fitness/default.nix` | — | ~~DB passwords not yet moved to SOPS~~ — resolved; secrets now via `mkSopsEnvFile`; run `sops secrets/nas-secrets.yaml` to add real values for `jallen-nas/sparky-fitness/{db-password,api-encryption-key,auth-secret}` |
| `modules/nixos/services/your-spotify/default.nix` | 36 | Spotify API keys not yet moved to SOPS |
| `modules/nixos/services/booklore/default.nix` | 25 | Database password not yet a SOPS secret |
| `packages/raspberrypi/udev-rules/default.nix` | 33 | `15-i2c-modprobe.rules` disabled; `i2cprobe` script not ported |

16
flake.lock generated
View File

@@ -1071,16 +1071,16 @@
},
"nixpkgs-unstable": {
"locked": {
"lastModified": 1773999129,
"narHash": "sha256-YbW6qhVebC8xlQRBxoxctDpzViQb4+6bX7Dbm/UJ44A=",
"lastModified": 1773821835,
"narHash": "sha256-TJ3lSQtW0E2JrznGVm8hOQGVpXjJyXY2guAxku2O9A4=",
"owner": "NixOS",
"repo": "nixpkgs",
"rev": "c3961540aa9cf997445f11220ff1b3673e864992",
"rev": "b40629efe5d6ec48dd1efba650c797ddbd39ace0",
"type": "github"
},
"original": {
"owner": "NixOS",
"ref": "nixos-unstable-small",
"ref": "nixos-unstable",
"repo": "nixpkgs",
"type": "github"
}
@@ -1215,16 +1215,16 @@
},
"nixpkgs_9": {
"locked": {
"lastModified": 1773999129,
"narHash": "sha256-YbW6qhVebC8xlQRBxoxctDpzViQb4+6bX7Dbm/UJ44A=",
"lastModified": 1773821835,
"narHash": "sha256-TJ3lSQtW0E2JrznGVm8hOQGVpXjJyXY2guAxku2O9A4=",
"owner": "NixOS",
"repo": "nixpkgs",
"rev": "c3961540aa9cf997445f11220ff1b3673e864992",
"rev": "b40629efe5d6ec48dd1efba650c797ddbd39ace0",
"type": "github"
},
"original": {
"owner": "NixOS",
"ref": "nixos-unstable-small",
"ref": "nixos-unstable",
"repo": "nixpkgs",
"type": "github"
}

View File

@@ -1,6 +1,6 @@
{
inputs = rec {
nixpkgs-unstable.url = "github:NixOS/nixpkgs/nixos-unstable-small";
nixpkgs-unstable.url = "github:NixOS/nixpkgs/nixos-unstable";
nixpkgs-stable.url = "github:NixOS/nixpkgs/nixos-25.11";
# Fork required: openthread-border-router is not yet in nixpkgs-unstable.

View File

@@ -78,7 +78,7 @@ in
command = "${pkgs.nodejs_24}/bin/npm";
args = [
"-y"
"mcp-server-code-runner@latest"
"@iflow-mcp/mcp-server-code-runner"
];
};
};

View File

@@ -357,8 +357,8 @@ in
};
recorder = {
# db_url = "postgresql://@/hass"; # local DB
db_url = "postgresql://homeassistant@10.0.1.3/homeassistant";
# Connect via Unix socket — peer auth via identMap maps OS user 'hass' → DB user 'homeassistant'.
db_url = "postgresql://homeassistant@/homeassistant?host=/run/postgresql";
purge_keep_days = 180;
};

View File

@@ -91,14 +91,14 @@ let
}
];
# Database configuration
# Database configuration — connect via Unix socket (peer auth via identMap)
database = {
name = "psycopg2";
allow_unsafe_locale = true;
args = {
user = "synapse";
database = "synapse";
host = "localhost";
host = "/run/postgresql";
cp_min = 5;
cp_max = 10;
};

View File

@@ -5,7 +5,7 @@
...
}:
let
inherit (lib.${namespace}) mkContainerService;
inherit (lib.${namespace}) mkContainerService mkSopsEnvFile;
serverName = "sparky-fitness-server";
frontendName = "sparky-fitness";
@@ -17,6 +17,27 @@ let
in
{
imports = [
# Sops env-file for sparky-fitness-server secrets
{
config = lib.mkIf serverCfg.enable (mkSopsEnvFile {
name = "sparky-fitness-server.env";
restartUnit = "podman-sparky-fitness-server.service";
secrets = {
"jallen-nas/sparky-fitness/db-password" = { };
"jallen-nas/sparky-fitness/api-encryption-key" = { };
"jallen-nas/sparky-fitness/auth-secret" = { };
};
content = ''
SPARKY_FITNESS_DB_PASSWORD=${config.sops.placeholder."jallen-nas/sparky-fitness/db-password"}
SPARKY_FITNESS_APP_DB_PASSWORD=${config.sops.placeholder."jallen-nas/sparky-fitness/db-password"}
SPARKY_FITNESS_API_ENCRYPTION_KEY=${
config.sops.placeholder."jallen-nas/sparky-fitness/api-encryption-key"
}
BETTER_AUTH_SECRET=${config.sops.placeholder."jallen-nas/sparky-fitness/auth-secret"}
'';
});
}
(mkContainerService {
inherit config;
name = serverName;
@@ -26,6 +47,7 @@ in
"${serverCfg.configDir}/sparky-fitness/server/backup:/app/SparkyFitnessServer/backup"
"${serverCfg.configDir}/sparky-fitness/server/uploads:/app/SparkyFitnessServer/uploads"
];
environmentFiles = [ config.sops.templates."sparky-fitness-server.env".path ];
environment = {
SPARKY_FITNESS_LOG_LEVEL = "0";
ALLOW_PRIVATE_NETWORK_CORS = "false";
@@ -33,13 +55,8 @@ in
SPARKY_FITNESS_DB_USER = "sparkyfitness";
SPARKY_FITNESS_DB_HOST = "10.0.1.3";
SPARKY_FITNESS_DB_NAME = "sparkyfitness";
# TODO: move DB password and secrets to sops
SPARKY_FITNESS_DB_PASSWORD = "sparkyfitness";
SPARKY_FITNESS_APP_DB_USER = "sparkyfitness";
SPARKY_FITNESS_APP_DB_PASSWORD = "sparkyfitness";
SPARKY_FITNESS_DB_PORT = "${toString dbCfg.port}";
SPARKY_FITNESS_API_ENCRYPTION_KEY = "088ab2c6487ca1048c1fe74a4d8bd906e88db56953406769426b615d6df2407b";
BETTER_AUTH_SECRET = "a0304bda5a9efd0d92595c8d46526e33d58f436408f6b70ea37c2b84308d9abe";
SPARKY_FITNESS_FRONTEND_URL = "http://10.0.1.3:${toString frontendCfg.port}";
SPARKY_FITNESS_DISABLE_SIGNUP = "false";
SPARKY_FITNESS_ADMIN_EMAIL = "jalle008@proton.me";
@@ -67,7 +84,7 @@ in
"${dbCfg.configDir}/sparky-fitness/db:/var/lib/postgresql/data"
];
environment = {
POSTGRES_DB = "sparkyfitness-db";
POSTGRES_DB = "sparkyfitness";
POSTGRES_USER = "sparkyfitness";
# TODO: move POSTGRES_PASSWORD to sops
POSTGRES_PASSWORD = "sparkyfitness";

View File

@@ -1,36 +0,0 @@
# Workaround for cosmic-applets 1.0.8 build failure:
# The Cargo.lock references https://github.com/pop-os/cosmic-settings at two
# different commits (b46a55d and 55b502d), which cargoSetupHook rejects:
# "Sources are not allowed to be defined multiple times."
# Using importCargoLock (via cargoDeps override) instead of fetchCargoVendor
# (cargoHash) avoids this check. Same pattern as cosmic-settings-daemon.
{ ... }:
final: prev: {
cosmic-applets = prev.cosmic-applets.overrideAttrs (old: {
cargoDeps = final.rustPlatform.importCargoLock {
lockFile = "${old.src}/Cargo.lock";
outputHashes = {
"accesskit-0.16.0" = "sha256-uoLcd116WXQTu1ZTfJDEl9+3UPpGBN/QuJpkkGyRADQ=";
"atomicwrites-0.4.2" = "sha256-QZSuGPrJXh+svMeFWqAXoqZQxLq/WfIiamqvjJNVhxA=";
"clipboard_macos-0.1.0" = "sha256-+8CGmBf1Gl9gnBDtuKtkzUE5rySebhH7Bsq/kNlJofY=";
"cosmic-client-toolkit-0.2.0" = "sha256-ymn+BUTTzyHquPn4hvuoA3y1owFj8LVrmsPu2cdkFQ8=";
"cosmic-comp-config-0.1.0" = "sha256-uUpRd8bR2TyD7Y1lpKmJTaTNv9yNsZVnr0oWDQgHD/0=";
"cosmic-config-1.0.0" = "sha256-EDFFtQ+yiclZ1wrcbSHFhmx7d6rAPlU+qq/gh1HGqv8=";
"cosmic-dbus-a11y-0.1.0" = "sha256-1yVIL3SQnOEtTHoLiZgBH21holNxcOuToyQ+QdvqoBg=";
"cosmic-freedesktop-icons-0.4.0" = "sha256-D4bWHQ4Dp8UGiZjc6geh2c2SGYhB7mX13THpCUie1c4=";
"cosmic-notifications-config-0.1.0" = "sha256-41F8TtXvZ+EMM3zHHfadwTFCte+ZXC+hP25J8QQPrTE=";
"cosmic-panel-config-0.1.0" = "sha256-1Xwe1uONJbl4wq6QBbTI1suLiSlTzU4e/5WBccvghHE=";
"cosmic-pipewire-1.0.0" = "sha256-yqrYF4zDd5yh5oCJUttsHDCEOS6xmH/9M5Hd9kgU9yw=";
"cosmic-settings-a11y-manager-subscription-1.0.2" =
"sha256-OIVG0snnYtRkL8D3nurlygkqx6ugzIV4RPm7wReaE4o=";
"cosmic-settings-config-0.1.0" = "sha256-4YozCuj6lF9GmsV9eRD4HEb3G8tYKjQc3+ghYHxKrhE=";
"cosmic-text-0.17.1" = "sha256-NHjJBE/WSMhN29CKTuB7PyJv4y2JByi5pyTUDtVoF7g=";
"cosmic-time-0.4.0" = "sha256-D3+GjRigubsBD8VdCpKWXgphstbOn/ayHDel04xBP4U=";
"dpi-0.1.1" = "sha256-Saw9LIWIbOaxD5/yCSqaN71Tzn2NXFzJMorH8o58ktw=";
"iced_glyphon-0.6.0" = "sha256-u1vnsOjP8npQ57NNSikotuHxpi4Mp/rV9038vAgCsfQ=";
"smithay-clipboard-0.8.0" = "sha256-4InFXm0ahrqFrtNLeqIuE3yeOpxKZJZx+Bc0yQDtv34=";
"softbuffer-0.4.1" = "sha256-/ocK79Lr5ywP/bb5mrcm7eTzeBbwpOazojvFUsAjMKM=";
};
};
});
}

View File

@@ -1,31 +0,0 @@
# Workaround for cosmic-settings-daemon 1.0.8 build failure:
# The Cargo.lock references https://github.com/pop-os/dbus-settings-bindings
# at two different commits (3b86984 and 0fa672f8), which cargoSetupHook
# rejects ("Sources are not allowed to be defined multiple times").
#
# Using importCargoLock (cargoLock) instead of fetchCargoVendor (cargoHash)
# avoids this check. We override cargoDeps directly since cargoLock is
# consumed by buildRustPackage before reaching mkDerivation.
{ ... }:
final: prev: {
cosmic-settings-daemon = prev.cosmic-settings-daemon.overrideAttrs (old: {
cargoDeps = final.rustPlatform.importCargoLock {
lockFile = "${old.src}/Cargo.lock";
outputHashes = {
"atomicwrites-0.4.2" = "sha256-QZSuGPrJXh+svMeFWqAXoqZQxLq/WfIiamqvjJNVhxA=";
"clipboard_macos-0.1.0" = "sha256-+8CGmBf1Gl9gnBDtuKtkzUE5rySebhH7Bsq/kNlJofY=";
"cosmic-client-toolkit-0.1.0" = "sha256-KvXQJ/EIRyrlmi80WKl2T9Bn+j7GCfQlcjgcEVUxPkc=";
"cosmic-comp-config-0.1.0" = "sha256-H2eMYjJi9VXv6D5IREVjfqR46hC9dxT84lk9Ubpnhpk=";
"cosmic-config-1.0.0" = "sha256-JzryxfdMMn4Ew5lKCpirzT50Rd5egudfXXTSql0iFas=";
"cosmic-dbus-a11y-0.1.0" = "sha256-CEmzl/09rD11kgnoHP2Q6N/emDhEK4wQiqSXmIlsbPE=";
"cosmic-freedesktop-icons-0.4.0" = "sha256-D4bWHQ4Dp8UGiZjc6geh2c2SGYhB7mX13THpCUie1c4=";
"cosmic-settings-daemon-0.1.0" = "sha256-QIupze3m2au51yJWsBylz2rBfeqreFX2D/F2+JbIWmg=";
"cosmic-settings-subscriptions-0.1.0" = "sha256-PSp7a80TO6z7b+Gkf5jHz7KNVNfc29HF8DFqEjkC75o=";
"cosmic-text-0.17.1" = "sha256-NHjJBE/WSMhN29CKTuB7PyJv4y2JByi5pyTUDtVoF7g=";
"iced_glyphon-0.6.0" = "sha256-u1vnsOjP8npQ57NNSikotuHxpi4Mp/rV9038vAgCsfQ=";
"smithay-clipboard-0.8.0" = "sha256-4InFXm0ahrqFrtNLeqIuE3yeOpxKZJZx+Bc0yQDtv34=";
"softbuffer-0.4.1" = "sha256-/ocK79Lr5ywP/bb5mrcm7eTzeBbwpOazojvFUsAjMKM=";
};
};
});
}

File diff suppressed because one or more lines are too long

View File

@@ -203,7 +203,7 @@ in
};
sparky-fitness-db = {
enable = false;
port = 5433;
port = 5432;
};
sparky-fitness-server = {
enable = true;

View File

@@ -1,4 +1,5 @@
{
lib,
pkgs,
...
}:
@@ -75,24 +76,38 @@ in
ensureDBOwnership = true;
}
];
# Allow access via pg_hba.conf rules:10.88.0.63
authentication = pkgs.lib.mkOverride 50 ''
# TYPE DATABASE USER ADDRESS METHOD
local all all trust
host homeassistant homeassistant 10.0.1.0/24 trust
local nextcloud nextcloud trust
host nextcloud nextcloud 10.0.1.0/24 trust
host nextcloud nextcloud ::1/128 trust
local onlyoffice onlyoffice trust
host onlyoffice onlyoffice 10.0.1.0/24 trust
local synapse synapse trust
host synapse synapse ::1/128 trust
local sparkyfitness sparkyfitness trust
host sparkyfitness sparkyfitness ::1/128 trust
# pg_hba.conf — use lib.mkForce to replace the module defaults entirely.
#
# Connection matrix:
# postgres (admin) — Unix socket, peer (OS user postgres = DB user postgres)
# authentik — Unix socket, peer (OS user authentik = DB user authentik)
# nextcloud — Unix socket, peer (OS user nextcloud = DB user nextcloud)
# homeassistant — Unix socket, peer via identMap (OS user hass → DB user homeassistant)
# synapse — Unix socket, peer via identMap (OS user matrix-synapse → DB user synapse)
# onlyoffice — Unix socket, peer (OS user onlyoffice = DB user onlyoffice) [disabled]
# sparkyfitness — Podman container TCP (10.88.0.0/16), scram-sha-256
authentication = lib.mkForce ''
# TYPE DATABASE USER ADDRESS METHOD
# All local Unix socket connections use peer auth (with identMap for mismatched names)
local all all peer map=system
# Podman container network sparkyfitness server connects via host LAN IP
host sparkyfitness sparkyfitness 10.88.0.0/16 scram-sha-256
'';
initialScript = pkgs.writeText "init-sql-script" ''
alter user sparkyfitness with password 'sparkyfitness';
# identMap — maps OS usernames to PostgreSQL usernames for peer auth.
# The catch-all regex rule (/^(.*)$ \1) allows any OS user whose name matches
# their DB user directly (authentik, nextcloud, onlyoffice, postgres).
# Explicit entries cover the mismatches.
identMap = lib.mkForce ''
# MAPNAME OS-USERNAME DB-USERNAME
system hass homeassistant
system matrix-synapse synapse
system /^(.*)$ \1
'';
# TODO: set sparkyfitness password declaratively via ensureUsers.*.ensureClauses.password
# once the SCRAM-SHA-256 hash is stored in SOPS (jallen-nas/sparky-fitness/db-password).
# The old initialScript has been removed — it only ran on first DB init and is now stale.
};
mysql = {

View File

@@ -257,6 +257,22 @@ in
sopsFile = defaultSops;
};
# ------------------------------
# sparky-fitness
# ------------------------------
"jallen-nas/sparky-fitness/db-password" = {
sopsFile = defaultSops;
restartUnits = [ "podman-sparky-fitness-server.service" ];
};
"jallen-nas/sparky-fitness/api-encryption-key" = {
sopsFile = defaultSops;
restartUnits = [ "podman-sparky-fitness-server.service" ];
};
"jallen-nas/sparky-fitness/auth-secret" = {
sopsFile = defaultSops;
restartUnits = [ "podman-sparky-fitness-server.service" ];
};
# ------------------------------
# authentik-rac
# NOTE: add to nas-secrets.yaml via `sops secrets/nas-secrets.yaml`: