self: { config, lib, ... }: let cfg = config.services.jetpham-website; package = self.packages.x86_64-linux.default; qaApi = self.packages.x86_64-linux.qa-api; in { options.services.jetpham-website = { enable = lib.mkEnableOption "Jet Pham's personal website"; domain = lib.mkOption { type = lib.types.str; default = "jetpham.com"; description = "Domain to serve the website on."; }; envFile = lib.mkOption { type = lib.types.nullOr lib.types.path; default = null; description = "Environment file containing QA_NOTIFY_EMAIL."; }; qaMailDomain = lib.mkOption { type = lib.types.str; default = "extremist.software"; description = "Mail domain for Q&A reply addresses."; }; webhookSecretFile = lib.mkOption { type = lib.types.nullOr lib.types.path; default = null; description = "File containing the WEBHOOK_SECRET for MTA Hook authentication."; }; }; config = lib.mkIf cfg.enable { # Q&A API systemd service systemd.services.jetpham-qa-api = { description = "Jet Pham Q&A API"; after = [ "network.target" ]; wantedBy = [ "multi-user.target" ]; serviceConfig = { DynamicUser = true; StateDirectory = "jetpham-qa"; Environment = [ "QA_DB_PATH=/var/lib/jetpham-qa/qa.db" ]; Restart = "on-failure"; RestartSec = 5; } // lib.optionalAttrs (cfg.webhookSecretFile == null) { ExecStart = "${qaApi}/bin/jetpham-qa-api"; } // lib.optionalAttrs (cfg.envFile != null) { EnvironmentFile = cfg.envFile; } // lib.optionalAttrs (cfg.webhookSecretFile != null) { LoadCredential = "webhook-secret:${cfg.webhookSecretFile}"; }; script = lib.mkIf (cfg.webhookSecretFile != null) '' export WEBHOOK_SECRET="$(cat $CREDENTIALS_DIRECTORY/webhook-secret)" exec ${qaApi}/bin/jetpham-qa-api ''; }; services.caddy.virtualHosts.${cfg.domain} = { extraConfig = '' header Cross-Origin-Opener-Policy "same-origin" header Cross-Origin-Embedder-Policy "require-corp" handle /api/* { reverse_proxy 127.0.0.1:3001 } handle { root * ${package} try_files {path} /index.html file_server } ''; }; }; }