manatee: add self-hosted todo app
Wire the offline-first todo app (github: local /home/alex/code/todo) into manatee, following the app-module convention: - flake input `todo` (local git checkout for now; gitea URL commented) with nixpkgs following. - hosts/manatee/modules/todo: mod.todo option importing the app's NixOS module; runs on 127.0.0.1:8091, secureCookies, token from agenix; the host owns the nginx vhost (todo.ppp.pm, forceSSL + useACMEHost) and homepage card. - mod.todo.enable = true. - certs: todo.ppp.pm DNS-01 cert via hetzner. - home-assistant DNS updater: add `todo` to the Hetzner subdomain list. - secrets: todo-token.age (encrypted access token) + recipients in secrets.nix.
This commit is contained in:
Generated
+26
-4
@@ -877,11 +877,11 @@
|
|||||||
]
|
]
|
||||||
},
|
},
|
||||||
"locked": {
|
"locked": {
|
||||||
"lastModified": 1784906229,
|
"lastModified": 1785677859,
|
||||||
"narHash": "sha256-9ZzpwieFwushXgbZZj1W4i8uhI0dmLZCcQSb6qVhn18=",
|
"narHash": "sha256-ZXWSL0F1ZDzeLSXFGvRom89nOEq80gXghc+ky/qA/l8=",
|
||||||
"ref": "main",
|
"ref": "main",
|
||||||
"rev": "374e630d8fd0fa063753ffaa3537ada4fb4bc11e",
|
"rev": "f9894abfc9cd9c2a5dacb9fe3609b58f5d407392",
|
||||||
"revCount": 55,
|
"revCount": 69,
|
||||||
"type": "git",
|
"type": "git",
|
||||||
"url": "ssh://gitea@git.ppp.pm:1122/alex/puppy-tracker.git"
|
"url": "ssh://gitea@git.ppp.pm:1122/alex/puppy-tracker.git"
|
||||||
},
|
},
|
||||||
@@ -911,6 +911,7 @@
|
|||||||
"pppdotpm-site": "pppdotpm-site",
|
"pppdotpm-site": "pppdotpm-site",
|
||||||
"puppy-tracker": "puppy-tracker",
|
"puppy-tracker": "puppy-tracker",
|
||||||
"solo-referee": "solo-referee",
|
"solo-referee": "solo-referee",
|
||||||
|
"todo": "todo",
|
||||||
"whib-backend": "whib-backend",
|
"whib-backend": "whib-backend",
|
||||||
"whib-frontend": "whib-frontend"
|
"whib-frontend": "whib-frontend"
|
||||||
}
|
}
|
||||||
@@ -1042,6 +1043,27 @@
|
|||||||
"type": "github"
|
"type": "github"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"todo": {
|
||||||
|
"inputs": {
|
||||||
|
"nixpkgs": [
|
||||||
|
"nixpkgs"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"locked": {
|
||||||
|
"lastModified": 1786622639,
|
||||||
|
"narHash": "sha256-q28DCpRkhuFcysdWNio4mIsR5VlonXbM8G+DyxitRPo=",
|
||||||
|
"ref": "main",
|
||||||
|
"rev": "a43e443720c3cc3fc38e9367bdac32e6f046c238",
|
||||||
|
"revCount": 17,
|
||||||
|
"type": "git",
|
||||||
|
"url": "file:///home/alex/code/todo"
|
||||||
|
},
|
||||||
|
"original": {
|
||||||
|
"ref": "main",
|
||||||
|
"type": "git",
|
||||||
|
"url": "file:///home/alex/code/todo"
|
||||||
|
}
|
||||||
|
},
|
||||||
"whib-backend": {
|
"whib-backend": {
|
||||||
"inputs": {
|
"inputs": {
|
||||||
"nixpkgs": [
|
"nixpkgs": [
|
||||||
|
|||||||
@@ -98,6 +98,15 @@
|
|||||||
# url = "path:/home/alex/code/solo-referee";
|
# url = "path:/home/alex/code/solo-referee";
|
||||||
inputs.nixpkgs.follows = "nixpkgs";
|
inputs.nixpkgs.follows = "nixpkgs";
|
||||||
};
|
};
|
||||||
|
|
||||||
|
todo = {
|
||||||
|
# Not yet pushed to gitea; using the local git checkout for now (git+file
|
||||||
|
# respects .gitignore, so web/node_modules isn't copied into the store).
|
||||||
|
# Flip these once the repo is published, matching the other apps above.
|
||||||
|
# url = "git+ssh://gitea@git.ppp.pm:1122/alex/todo.git?ref=main";
|
||||||
|
url = "git+file:///home/alex/code/todo?ref=main";
|
||||||
|
inputs.nixpkgs.follows = "nixpkgs";
|
||||||
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
outputs =
|
outputs =
|
||||||
|
|||||||
@@ -59,6 +59,19 @@
|
|||||||
"--http-timeout=60"
|
"--http-timeout=60"
|
||||||
];
|
];
|
||||||
};
|
};
|
||||||
|
|
||||||
|
"todo.ppp.pm" = {
|
||||||
|
dnsProvider = "hetzner";
|
||||||
|
environmentFile = config.age.secrets.hetzner-dns.path;
|
||||||
|
group = "nginx";
|
||||||
|
|
||||||
|
extraLegoFlags = [
|
||||||
|
"--dns.resolvers=1.1.1.1:53,8.8.8.8:53"
|
||||||
|
"--dns.propagation-wait=60s"
|
||||||
|
"--dns-timeout=60"
|
||||||
|
"--http-timeout=60"
|
||||||
|
];
|
||||||
|
};
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@@ -27,6 +27,7 @@ in
|
|||||||
disk-smart.enable = true;
|
disk-smart.enable = true;
|
||||||
puppy-tracker.enable = true;
|
puppy-tracker.enable = true;
|
||||||
solo-referee.enable = true;
|
solo-referee.enable = true;
|
||||||
|
todo.enable = true;
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -251,7 +251,7 @@ in
|
|||||||
];
|
];
|
||||||
|
|
||||||
script = ''
|
script = ''
|
||||||
SUBDOMAINS="ha komga romm puppy"
|
SUBDOMAINS="ha komga romm puppy todo"
|
||||||
INTERFACE="enp3s0"
|
INTERFACE="enp3s0"
|
||||||
|
|
||||||
CURRENT_IP=$(curl -s --fail --interface "$INTERFACE" ifconfig.me)
|
CURRENT_IP=$(curl -s --fail --interface "$INTERFACE" ifconfig.me)
|
||||||
|
|||||||
@@ -0,0 +1,58 @@
|
|||||||
|
{
|
||||||
|
inputs,
|
||||||
|
lib,
|
||||||
|
config,
|
||||||
|
...
|
||||||
|
}:
|
||||||
|
let
|
||||||
|
enabled = config.mod.todo.enable;
|
||||||
|
nginxEnabled = config.mod.nginx.enable;
|
||||||
|
port = 8091;
|
||||||
|
in
|
||||||
|
{
|
||||||
|
options = {
|
||||||
|
mod.todo = {
|
||||||
|
enable = lib.mkEnableOption "Enable todo module";
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
imports = [
|
||||||
|
inputs.todo.nixosModules.default
|
||||||
|
];
|
||||||
|
|
||||||
|
config = lib.mkIf enabled {
|
||||||
|
mod.homepage.services = [
|
||||||
|
{
|
||||||
|
name = "Todo";
|
||||||
|
port = port;
|
||||||
|
description = "Offline-first todo";
|
||||||
|
# Login needs HTTPS (Secure cookies), so link to the public vhost.
|
||||||
|
url = "https://todo.ppp.pm";
|
||||||
|
}
|
||||||
|
];
|
||||||
|
|
||||||
|
services.todo = {
|
||||||
|
enable = true;
|
||||||
|
address = "127.0.0.1";
|
||||||
|
inherit port;
|
||||||
|
# Served publicly over HTTPS via the nginx vhost below.
|
||||||
|
secureCookies = true;
|
||||||
|
tokenFile = config.age.secrets."todo-token".path;
|
||||||
|
# sessionSecretFile is left unset: the app generates one in its state dir
|
||||||
|
# (/var/lib/todo) on first boot, mode 0600.
|
||||||
|
};
|
||||||
|
|
||||||
|
services.nginx = lib.mkIf nginxEnabled {
|
||||||
|
virtualHosts."todo.ppp.pm" = {
|
||||||
|
forceSSL = true;
|
||||||
|
useACMEHost = "todo.ppp.pm";
|
||||||
|
|
||||||
|
locations."/" = {
|
||||||
|
proxyPass = "http://127.0.0.1:${toString port}";
|
||||||
|
};
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
age.secrets."todo-token".file = ../../../../secrets/manatee/todo-token.age;
|
||||||
|
};
|
||||||
|
}
|
||||||
@@ -0,0 +1,8 @@
|
|||||||
|
age-encryption.org/v1
|
||||||
|
-> ssh-ed25519 wkRvNA 11epAkGKr0IpXqtWGQ73rZUsiWQRlL++fc2B2TvQ90M
|
||||||
|
lSKGeNiL82UIyhg1wrY9ylltFcITDffJLgA6j02eS2M
|
||||||
|
-> ssh-ed25519 +oNaHQ pg1rC56bQRxO2Eb5onV8TkeB/Wsc7HhvufBfslkK+gA
|
||||||
|
znYqNOBhQX9bx5k07vVTHye/RLxOAkQ2dCagZWyWBkQ
|
||||||
|
--- Dxthx4NFJfe26jFnXH/3NYILME+tlO2FUsSVGCP4ucY
|
||||||
|
°]œê&Ì�¥ü…²�+/ªÖ×Dš‘�ô[6HIÂe>™“‚¾ÛIà Ná¡1Ak¬’ä4ZHG
|
||||||
|
T}o8×f<Û¦r<Â
|
||||||
@@ -44,6 +44,7 @@ in {
|
|||||||
"manatee/romm-metadata-api-keys.age".publicKeys = [ manatee alex ];
|
"manatee/romm-metadata-api-keys.age".publicKeys = [ manatee alex ];
|
||||||
"manatee/puppy-tracker-invite-code.age".publicKeys = [ manatee alex ];
|
"manatee/puppy-tracker-invite-code.age".publicKeys = [ manatee alex ];
|
||||||
"manatee/solo-referee-api-key.age".publicKeys = [ manatee alex ];
|
"manatee/solo-referee-api-key.age".publicKeys = [ manatee alex ];
|
||||||
|
"manatee/todo-token.age".publicKeys = [ manatee alex ];
|
||||||
|
|
||||||
"backwards/root.backwards.age".publicKeys = [ backwards alex ];
|
"backwards/root.backwards.age".publicKeys = [ backwards alex ];
|
||||||
"backwards/root.backwards.pub.age".publicKeys = [ backwards alex ];
|
"backwards/root.backwards.pub.age".publicKeys = [ backwards alex ];
|
||||||
|
|||||||
Reference in New Issue
Block a user