Kieran's opinionated (and probably slightly dumb) nix config
at main 3.4 kB view raw
1{ 2 config, 3 lib, 4 pkgs, 5 ... 6}: 7let 8 cfg = config.atelier.services.cachet; 9in 10{ 11 options.atelier.services.cachet = { 12 enable = lib.mkEnableOption "Cachet Slack emoji/profile cache"; 13 14 domain = lib.mkOption { 15 type = lib.types.str; 16 description = "Domain to serve cachet on"; 17 }; 18 19 port = lib.mkOption { 20 type = lib.types.port; 21 default = 3000; 22 description = "Port to run cachet on"; 23 }; 24 25 dataDir = lib.mkOption { 26 type = lib.types.path; 27 default = "/var/lib/cachet"; 28 description = "Directory to store cachet data"; 29 }; 30 31 secretsFile = lib.mkOption { 32 type = lib.types.path; 33 description = "Path to secrets file containing SLACK_TOKEN, SLACK_SIGNING_SECRET, BEARER_TOKEN"; 34 }; 35 36 repository = lib.mkOption { 37 type = lib.types.str; 38 default = "https://github.com/taciturnaxolotl/cachet.git"; 39 description = "Git repository URL (optional, for auto-deployment)"; 40 }; 41 42 autoUpdate = lib.mkEnableOption "Automatically git pull on service restart"; 43 }; 44 45 config = lib.mkIf cfg.enable { 46 users.groups.services = { }; 47 48 users.users.cachet = { 49 isSystemUser = true; 50 group = "cachet"; 51 extraGroups = [ "services" ]; 52 home = cfg.dataDir; 53 createHome = true; 54 shell = pkgs.bash; 55 }; 56 57 users.groups.cachet = { }; 58 59 security.sudo.extraRules = [ 60 { 61 users = [ "cachet" ]; 62 commands = [ 63 { 64 command = "/run/current-system/sw/bin/systemctl restart cachet.service"; 65 options = [ "NOPASSWD" ]; 66 } 67 ]; 68 } 69 ]; 70 71 systemd.services.cachet = { 72 description = "Cachet Slack emoji/profile cache"; 73 wantedBy = [ "multi-user.target" ]; 74 after = [ "network.target" ]; 75 path = [ pkgs.git ]; 76 77 preStart = '' 78 if [ ! -d ${cfg.dataDir}/app/.git ]; then 79 ${pkgs.git}/bin/git clone ${cfg.repository} ${cfg.dataDir}/app 80 fi 81 82 cd ${cfg.dataDir}/app 83 '' + lib.optionalString cfg.autoUpdate '' 84 ${pkgs.git}/bin/git pull 85 '' + '' 86 87 if [ ! -f src/index.ts ]; then 88 echo "No code found at ${cfg.dataDir}/app/src/index.ts" 89 exit 1 90 fi 91 92 echo "Installing dependencies..." 93 ${pkgs.unstable.bun}/bin/bun install 94 ''; 95 96 serviceConfig = { 97 Type = "simple"; 98 User = "cachet"; 99 Group = "cachet"; 100 EnvironmentFile = cfg.secretsFile; 101 Environment = [ 102 "NODE_ENV=production" 103 "PORT=${toString cfg.port}" 104 "DATABASE_PATH=${cfg.dataDir}/data/cachet.db" 105 ]; 106 ExecStart = "${pkgs.bash}/bin/bash -c 'cd ${cfg.dataDir}/app && ${pkgs.unstable.bun}/bin/bun run src/index.ts'"; 107 Restart = "always"; 108 RestartSec = "10s"; 109 }; 110 111 serviceConfig.ExecStartPre = [ 112 "+${pkgs.writeShellScript "cachet-setup" '' 113 mkdir -p ${cfg.dataDir}/data 114 mkdir -p ${cfg.dataDir}/app 115 chown -R cachet:services ${cfg.dataDir} 116 chmod -R g+rwX ${cfg.dataDir} 117 ''}" 118 ]; 119 }; 120 121 services.caddy.virtualHosts.${cfg.domain} = { 122 extraConfig = '' 123 tls { 124 dns cloudflare {env.CLOUDFLARE_API_TOKEN} 125 } 126 127 reverse_proxy localhost:${toString cfg.port} 128 ''; 129 }; 130 }; 131}