{ lib, pkgs, config, ... }: let cfg = config.services.forgejo; srv = cfg.settings.server; fqdn = "git.symbiotrip.com"; smtpPassword = "Monaco55"; runnerToken = "PUT_RUNNER_REGISTRATION_TOKEN_HERE"; adminPassword = "2wiggyWah!"; adminUser = "jsutter"; adminEmail = "jsutter@symbiotrip.com"; in { # DNS-based ACME certificate configuration # Uses defaults (dnsProvider, email, credentials) from nginx.nix security.acme.certs.${fqdn} = { # Group needs to be set so nginx can read the certificate group = config.services.nginx.group; # Inherit DNS challenge configuration from security.acme.defaults (set in nginx.nix) # This includes: dnsProvider = "cloudflare", environmentFile with Cloudflare token, email # Explicitly ensure DNS mode (not HTTP-01) webroot = null; }; # Nginx virtual host for Forgejo services.nginx.virtualHosts.${fqdn} = { # CRITICAL FIX: Don't set enableACME = true # That would create an HTTP-01 challenge handler, which conflicts with DNS challenge # Instead, we use useACMEHost to reference the DNS-obtained certificate enableACME = false; # Disable automatic ACME for this vhost useACMEHost = fqdn; # Use the certificate obtained via DNS challenge forceSSL = true; # acmeRoot is not needed/used with DNS challenge method # acmeRoot = null; # Removed - implicit with enableACME = false extraConfig = '' client_max_body_size 512M; proxy_set_header Host $host; proxy_set_header X-Forwarded-Proto $scheme; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; # Logging for debugging access_log /var/log/nginx/${fqdn}-access.log; error_log /var/log/nginx/${fqdn}-error.log warn; ''; locations."/".proxyPass = "http://localhost:${toString srv.HTTP_PORT}"; }; # Forgejo service configuration services.forgejo = { enable = true; database.type = "postgres"; lfs.enable = true; settings = { server = { DOMAIN = fqdn; ROOT_URL = "https://${fqdn}/"; HTTP_PORT = 3000; # Bind to localhost only - nginx handles public HTTPS LOCAL_ROOT_URL = "http://localhost:3000/"; }; service.DISABLE_REGISTRATION = true; actions = { ENABLED = true; DEFAULT_ACTIONS_URL = "github"; }; mailer = { ENABLED = true; SMTP_ADDR = "mail.example.com"; FROM = "noreply@${fqdn}"; USER = "noreply@${fqdn}"; PASSWD = smtpPassword; }; }; }; # Ensure nginx starts after ACME certificate is available systemd.services.nginx = { after = [ "acme-${fqdn}.service" "acme-${fqdn}-renew.service" ]; requires = [ "acme-${fqdn}.service" ]; }; # Create/ensure admin user on startup systemd.services.forgejo.preStart = let adminCmd = "${lib.getExe cfg.package} admin user"; in '' ${adminCmd} create \ --admin \ --username ${adminUser} \ --email "${adminEmail}" \ --password "${adminPassword}" \ --must-change-password=false || true ''; # Enable Docker for Forgejo Actions runner virtualisation.docker.enable = true; # Configure Forgejo Actions runner services.gitea-actions-runner = { package = pkgs.forgejo-runner; instances.default = { enable = true; name = "warp"; url = "https://${fqdn}"; token = runnerToken; labels = [ "node-22:docker://node:22-bookworm" "nixos-latest:docker://nixos/nix" # "native:host" ]; }; }; }