mirror of
https://github.com/nmasur/dotfiles
synced 2025-07-05 20:50:15 +00:00
update lockfile and add pgweb, fixes to cloudflare caddy
This commit is contained in:
@ -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
|
||||
];
|
||||
}
|
||||
];
|
||||
# Allow Caddy to read Cloudflare API key for DNS validation
|
||||
systemd.services.caddy.serviceConfig.EnvironmentFile = [
|
||||
config.secrets.cloudflare-api.dest
|
||||
config.secrets.letsencrypt-key.dest
|
||||
];
|
||||
systemd.services.caddy.serviceConfig = {
|
||||
# Allow Caddy to read Cloudflare API key for DNS validation
|
||||
# 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;
|
||||
|
||||
};
|
||||
}
|
||||
|
82
platforms/nixos/modules/nmasur/presets/services/pgweb.nix
Normal file
82
platforms/nixos/modules/nmasur/presets/services/pgweb.nix
Normal 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 ];
|
||||
|
||||
};
|
||||
}
|
@ -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
|
||||
|
@ -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,17 +37,37 @@ in
|
||||
Type = "simple";
|
||||
DynamicUser = true;
|
||||
StateDirectory = "cloudflare-dyndns-noproxy";
|
||||
EnvironmentFile = config.services.cloudflare-dyndns.apiTokenFile;
|
||||
ExecStart =
|
||||
let
|
||||
args =
|
||||
[ "--cache-file /var/lib/cloudflare-dyndns-noproxy/ip.cache" ]
|
||||
++ (if config.services.cloudflare-dyndns.ipv4 then [ "-4" ] else [ "-no-4" ])
|
||||
++ (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}";
|
||||
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" ]
|
||||
++ (if config.services.cloudflare-dyndns.ipv4 then [ "-4" ] else [ "-no-4" ])
|
||||
++ (if config.services.cloudflare-dyndns.ipv6 then [ "-6" ] else [ "-no-6" ])
|
||||
++ lib.optional config.services.cloudflare-dyndns.deleteMissing "--delete-missing";
|
||||
in
|
||||
''
|
||||
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}
|
||||
'';
|
||||
};
|
||||
};
|
||||
}
|
||||
|
Reference in New Issue
Block a user