update lockfile and add pgweb, fixes to cloudflare caddy

This commit is contained in:
Noah Masur 2025-05-03 19:25:32 +00:00
parent 54a073b946
commit bfbacbe93e
6 changed files with 168 additions and 52 deletions

60
flake.lock generated
View File

@ -22,11 +22,11 @@
]
},
"locked": {
"lastModified": 1743221873,
"narHash": "sha256-i8VPNm4UBsC3Ni6VwjojVJvCpS9GZ4vPrpFRtCGJzBs=",
"lastModified": 1746254942,
"narHash": "sha256-Y062AuRx6l+TJNX8wxZcT59SSLsqD9EedAY0mqgTtQE=",
"owner": "lnl7",
"repo": "nix-darwin",
"rev": "53d0f0ed11487a4476741fde757d0feabef4cc4e",
"rev": "760a11c87009155afa0140d55c40e7c336d62d7a",
"type": "github"
},
"original": {
@ -43,11 +43,11 @@
]
},
"locked": {
"lastModified": 1741786315,
"narHash": "sha256-VT65AE2syHVj6v/DGB496bqBnu1PXrrzwlw07/Zpllc=",
"lastModified": 1745812220,
"narHash": "sha256-hotBG0EJ9VmAHJYF0yhWuTVZpENHvwcJ2SxvIPrXm+g=",
"owner": "nix-community",
"repo": "disko",
"rev": "0d8c6ad4a43906d14abd5c60e0ffe7b587b213de",
"rev": "d0c543d740fad42fe2c035b43c9d41127e073c78",
"type": "github"
},
"original": {
@ -193,11 +193,11 @@
"rust-overlay": "rust-overlay"
},
"locked": {
"lastModified": 1743346877,
"narHash": "sha256-WczB9koq4xvdBZoMLW8VFT16RGaDrJXyA0rDTg2GFVU=",
"lastModified": 1746193606,
"narHash": "sha256-LD3ce/SlIY8Wr8XG52EI5t9bNa/peBCXykIJBvcGmO8=",
"owner": "helix-editor",
"repo": "helix",
"rev": "e148d8b3110ace99505c0871714cd64391cc4ba3",
"rev": "12139a4c30ad20d9a1b181de69532a57601cf96f",
"type": "github"
},
"original": {
@ -213,11 +213,11 @@
]
},
"locked": {
"lastModified": 1743346616,
"narHash": "sha256-AB/ve2el1TB7k4iyogHGCVlWVkrhp3+4FKKMr1W5iKQ=",
"lastModified": 1746243165,
"narHash": "sha256-DQycVmlyLQNLjLJ/FzpokVmbxGQ8HjQQ4zN4nyq2vII=",
"owner": "nix-community",
"repo": "home-manager",
"rev": "1d2ed9c503cf41ca7f3db091edc8519dcdcd8b41",
"rev": "c0962eeeabfb8127713f859ec8a5f0e86dead0f2",
"type": "github"
},
"original": {
@ -259,11 +259,11 @@
]
},
"locked": {
"lastModified": 1740943170,
"narHash": "sha256-A0F7T/euSMen004cVQN/ZkMpLkgLXDs+mq/merhd+0Y=",
"lastModified": 1745846717,
"narHash": "sha256-GjwZEjCrI1/tQYylAQ+hU5JYD2hJI+rZmfICCIniWuE=",
"owner": "gytis-ivaskevicius",
"repo": "nix2vim",
"rev": "a562f32ff2393d0ed198103c65a3035bcdf83d4d",
"rev": "0cd899a39b56d665115f72ffc7c37e0f4cf41dbe",
"type": "github"
},
"original": {
@ -310,11 +310,11 @@
},
"nixpkgs": {
"locked": {
"lastModified": 1743095683,
"narHash": "sha256-gWd4urRoLRe8GLVC/3rYRae1h+xfQzt09xOfb0PaHSk=",
"lastModified": 1746141548,
"narHash": "sha256-IgBWhX7A2oJmZFIrpRuMnw5RAufVnfvOgHWgIdds+hc=",
"owner": "nixos",
"repo": "nixpkgs",
"rev": "5e5402ecbcb27af32284d4a62553c019a3a49ea6",
"rev": "f02fddb8acef29a8b32f10a335d44828d7825b78",
"type": "github"
},
"original": {
@ -365,11 +365,11 @@
"treefmt-nix": "treefmt-nix"
},
"locked": {
"lastModified": 1743335104,
"narHash": "sha256-wEEHpF+h+9m2QvjYtIx11EMi+sXG3wS9f/QSE6KPpJs=",
"lastModified": 1746282980,
"narHash": "sha256-KOkO6aDwI8FOmMMv3MdO2WL95lMOJR4qDMUHPOoFtyM=",
"owner": "nix-community",
"repo": "nur",
"rev": "374adb7fb2c751f679519f8db532f726488293a0",
"rev": "e4be6680a4b231e712fef9c1cd5714f08a1ce51b",
"type": "github"
},
"original": {
@ -425,11 +425,11 @@
]
},
"locked": {
"lastModified": 1737080704,
"narHash": "sha256-n+J2h9GM9ZpFOQUmtZoCr1+DFF/iO5UlmLJeHIxbZGY=",
"lastModified": 1745116541,
"narHash": "sha256-5xzA6dTfqCfTTDCo3ipPZzrg3wp01xmcr73y4cTNMP8=",
"owner": "oxalica",
"repo": "rust-overlay",
"rev": "f9953fe89f8b65401fc4d4a288940bc2cb072949",
"rev": "e2142ef330a61c02f274ac9a9cb6f8487a5d0080",
"type": "github"
},
"original": {
@ -560,11 +560,11 @@
]
},
"locked": {
"lastModified": 1743125458,
"narHash": "sha256-0z+5AMacL2Eqo92fAd0eCWeKVecWrxPJwd5/BIfcdJ8=",
"lastModified": 1744290088,
"narHash": "sha256-/X9XVEl0EiyisNbF5srrxXRSVoRqdwExuqyspYqqEjQ=",
"owner": "nix-community",
"repo": "NixOS-WSL",
"rev": "394c77f61ac76399290bfc2ef9d47b1fba31b215",
"rev": "60b4904a1390ac4c89e93d95f6ed928975e525ed",
"type": "github"
},
"original": {
@ -582,11 +582,11 @@
"rust-overlay": "rust-overlay_2"
},
"locked": {
"lastModified": 1743344227,
"narHash": "sha256-Lp1JUMrhvAmCzftOSQ2Sr0+svemxSxcLeZ4HkmdLXbE=",
"lastModified": 1746209831,
"narHash": "sha256-1R1MRxHmTbNUASTCdJTaaIEUevx18+XpVVxEcb0q7VM=",
"owner": "sxyazi",
"repo": "yazi",
"rev": "1765aba68440f73c590cedac14ece6778fe88ff5",
"rev": "a201c93419bede1f35c69a6b8b21ebbf4a752e6e",
"type": "github"
},
"original": {

View File

@ -133,6 +133,7 @@
notifications = "ntfy.${baseName}";
paperless = "paper.${baseName}";
photos = "photos.${baseName}";
postgresql = "pg.${baseName}";
prometheus = "prom.${baseName}";
secrets = "vault.${baseName}";
smtp = "smtp.purelymail.com";

View File

@ -67,8 +67,8 @@ in
# Tell Caddy to use Cloudflare DNS for ACME challenge validation
services.caddy.package = pkgs.caddy.withPlugins {
plugins = [ "github.com/caddy-dns/cloudflare@v0.0.0-20250228175314-1fb64108d4de" ];
hash = "sha256-YYpsf8HMONR1teMiSymo2y+HrKoxuJMKIea5/NEykGc=";
plugins = [ "github.com/caddy-dns/cloudflare@v0.2.1" ];
hash = "sha256-saKJatiBZ4775IV2C5JLOmZ4BwHKFtRZan94aS5pO90=";
};
nmasur.presets.services.caddy.tlsPolicies = [
{
@ -90,11 +90,14 @@ in
];
}
];
systemd.services.caddy.serviceConfig = {
# Allow Caddy to read Cloudflare API key for DNS validation
systemd.services.caddy.serviceConfig.EnvironmentFile = [
config.secrets.cloudflare-api.dest
# Allow Caddy to use letsencrypt account key for TLS verification
EnvironmentFile = [
config.secrets.letsencrypt-key.dest
config.secrets.cloudflare-api-prefixed.dest
];
};
# Private key is used for LetsEncrypt
secrets.letsencrypt-key = {
@ -111,15 +114,21 @@ in
owner = "caddy";
group = "caddy";
};
secrets.cloudflare-api-prefixed = {
source = ./cloudflare-api.age;
dest = "${config.secretsDirectory}/cloudflare-api-prefixed";
owner = "caddy";
group = "caddy";
prefix = "CLOUDFLARE_API_TOKEN=";
};
# Wait for secret to exist
systemd.services.caddy = {
after = [
"cloudflare-api-secret.service"
"cloudflare-api-prefixed-secret.service"
"letsencrypt-key-secret.service"
];
requires = [
"cloudflare-api-secret.service"
"cloudflare-api-prefixed-secret.service"
"letsencrypt-key-secret.service"
];
};
@ -150,5 +159,8 @@ in
requires = [ "cloudflare-api-secret.service" ];
};
# Enable the home-made service that we created for non-proxied records
services.cloudflare-dyndns-noproxy.enable = true;
};
}

View File

@ -0,0 +1,82 @@
{
config,
pkgs,
lib,
...
}:
let
inherit (config.nmasur.settings) username hostnames;
cfg = config.nmasur.presets.services.pgweb;
in
{
options.nmasur.presets.services.pgweb = {
enable = lib.mkEnableOption "Postgres web UI";
port = lib.mkOption {
type = lib.types.port;
description = "Port to use for the localhost";
default = 8081;
};
};
config = lib.mkIf cfg.enable {
systemd.services.pgweb = {
description = "Postgres web UI";
after = [
"postgresql.target"
];
# requires = [ "pgweb-secret.service" ];
wantedBy = [ "multi-user.target" ];
serviceConfig = {
Type = "simple";
DynamicUser = false;
User = "postgres";
Group = "postgres";
StateDirectory = "pgweb";
ExecStart =
let
args = [
"--url postgres:///hippocampus?host=/run/postgresql"
];
in
"${lib.getExe pkgs.pgweb} ${toString args}";
};
};
# Allow web traffic to Caddy
nmasur.presets.services.caddy.routes = [
{
match = [ { host = [ hostnames.postgresql ]; } ];
handle = [
{
handler = "authentication";
providers = {
http_basic = {
hash = {
algorithm = "bcrypt";
};
accounts = [
{
username = username;
password = "$2a$14$dtzWBh7ZDNgqFIJTJO7Rxe15Y189agBiWKZFJbs4sZz7QhqGQAwJS";
}
];
};
};
}
{
handler = "reverse_proxy";
upstreams = [ { dial = "localhost:${builtins.toString cfg.port}"; } ];
}
];
}
];
# Configure Cloudflare DNS to point to this machine
services.cloudflare-dyndns.domains = [ hostnames.postgresql ];
};
}

View File

@ -28,6 +28,7 @@ in
grafana.enable = lib.mkDefault true;
influxdb2.enable = lib.mkDefault true;
litestream.enable = lib.mkDefault true;
pgweb.enable = lib.mkDefault true;
minecraft-server.enable = lib.mkDefault true;
n8n.enable = lib.mkDefault true;
nix-autoupgrade.enable = lib.mkDefault false; # On by default for communications

View File

@ -6,12 +6,12 @@
}:
let
cfg = config.services.cloudflare-dyndns-no-proxy;
cfg = config.services.cloudflare-dyndns-noproxy;
in
{
options.services.cloudflare-dyndns-no-proxy.enable = lib.mkEnableOption "Cloudflare dyndns client without proxying";
options.services.cloudflare-dyndns-noproxy.enable = lib.mkEnableOption "Cloudflare dyndns client without proxying";
config = lib.mkIf cfg.enable {
@ -37,8 +37,13 @@ in
Type = "simple";
DynamicUser = true;
StateDirectory = "cloudflare-dyndns-noproxy";
EnvironmentFile = config.services.cloudflare-dyndns.apiTokenFile;
ExecStart =
Environment = [ "XDG_CACHE_HOME=%S/cloudflare-dyndns-noproxy/.cache" ];
LoadCredential = [
"apiToken:${config.services.cloudflare-dyndns.apiTokenFile}"
];
};
script =
let
args =
[ "--cache-file /var/lib/cloudflare-dyndns-noproxy/ip.cache" ]
@ -46,8 +51,23 @@ in
++ (if config.services.cloudflare-dyndns.ipv6 then [ "-6" ] else [ "-no-6" ])
++ lib.optional config.services.cloudflare-dyndns.deleteMissing "--delete-missing";
in
"${pkgs.cloudflare-dyndns}/bin/cloudflare-dyndns ${toString args}";
};
''
export CLOUDFLARE_API_TOKEN_FILE=''${CREDENTIALS_DIRECTORY}/apiToken
echo $CLOUDFLARE_API_TOKEN_FILE
cat $CLOUDFLARE_API_TOKEN_FILE
# Added 2025-03-10: `cfg.apiTokenFile` used to be passed as an
# `EnvironmentFile` to the service, which required it to be of
# the form "CLOUDFLARE_API_TOKEN=" rather than just the secret.
# If we detect this legacy usage, error out.
token=$(< "''${CLOUDFLARE_API_TOKEN_FILE}")
if [[ $token == CLOUDFLARE_API_TOKEN* ]]; then
echo "Error: your api token starts with 'CLOUDFLARE_API_TOKEN='. Remove that, and instead specify just the token." >&2
exit 1
fi
exec ${lib.getExe pkgs.cloudflare-dyndns} ${toString args}
'';
};
};
}