From 6a3b5f3771aa8d58641b51089baec9b79062c67c Mon Sep 17 00:00:00 2001 From: Kalle Struik Date: Sun, 16 Feb 2025 12:30:00 +0100 Subject: [PATCH] Add forgejo role --- example_secrets.yaml | 11 +++ hosts/nix-test.nix | 2 + roles/authentik/default.nix | 3 + roles/default.nix | 1 + roles/forgejo.nix | 154 ++++++++++++++++++++++++++++++++++++ secrets/nix-test.yaml | 12 ++- 6 files changed, 181 insertions(+), 2 deletions(-) create mode 100644 roles/forgejo.nix diff --git a/example_secrets.yaml b/example_secrets.yaml index 47b6aa7..5d3d7be 100644 --- a/example_secrets.yaml +++ b/example_secrets.yaml @@ -11,6 +11,17 @@ authentik: email_from: mail@example.com email_username: mail@example.com email_password: ADifferentVeryLongSecurePassword +forgejo: + db_pass: AVeryLongSecurePassword + # Some of these are not really secret, but having it in one place is easier + email_host: mail.example.com + email_port: "587" + email_from: mail@example.com + email_username: mail@example.com + email_password: ADifferentVeryLongSecurePassword + postgres: # Every database used should have an entry with the password here authentik: AVeryLongSecurePassword + forgejo: AVeryLongSecurePassword + diff --git a/hosts/nix-test.nix b/hosts/nix-test.nix index 77b6c3e..f1a7248 100644 --- a/hosts/nix-test.nix +++ b/hosts/nix-test.nix @@ -14,10 +14,12 @@ traefik sonarr authentik + forgejo ]; config = { sonarr.domain = "service1.${hlConfig.domain}"; authentik.domain = "service2.${hlConfig.domain}"; + forgejo.domain = "service3.${hlConfig.domain}"; traefik.wildcardDomains = [ hlConfig.domain "pds.${hlConfig.domain}" diff --git a/roles/authentik/default.nix b/roles/authentik/default.nix index 44981b3..7e5323d 100644 --- a/roles/authentik/default.nix +++ b/roles/authentik/default.nix @@ -44,6 +44,9 @@ }; config = { + networking.firewall.allowedTCPPorts = [ + 9000 + ]; # Set up user to run authentik users.users."authentik" = { diff --git a/roles/default.nix b/roles/default.nix index 6b828ab..0c6ed7d 100644 --- a/roles/default.nix +++ b/roles/default.nix @@ -11,4 +11,5 @@ sonarr = utils.mkRole (import ./sonarr.nix); traefik = utils.mkRole (import ./traefik.nix); authentik = utils.mkRole (import ./authentik); + forgejo = utils.mkRole (import ./forgejo.nix); } diff --git a/roles/forgejo.nix b/roles/forgejo.nix new file mode 100644 index 0000000..c04c6ed --- /dev/null +++ b/roles/forgejo.nix @@ -0,0 +1,154 @@ +{ + name = "Forgejo"; + description = '' + Forgejo git server + ''; + + traefikRoutes = + { + host, + ... + }: + let + hostname = host.hostname; + config = host.config.forgejo; + in + [ + { + name = "${hostname}-forgejo"; + rule = "Host(`${config.domain}`)"; + target = "http://${host.ip}:3000"; + } + ]; + + nixosModule = + { + pkgs, + lib, + config, + ... + }: + { + options.forgejo = { + domain = lib.mkOption { + type = lib.types.str; + }; + }; + + config = + let + cfg = config.forgejo; + secrets = config.sops.secrets; + in + { + networking.firewall.allowedTCPPorts = [ + 3000 + ]; + + # Create the database + postgres.databases = [ "forgejo" ]; + + sops.secrets = { + "forgejo/db_pass" = { + owner = "forgejo"; + }; + "forgejo/email_host" = { + owner = "forgejo"; + }; + "forgejo/email_port" = { + owner = "forgejo"; + }; + "forgejo/email_from" = { + owner = "forgejo"; + }; + "forgejo/email_username" = { + owner = "forgejo"; + }; + "forgejo/email_password" = { + owner = "forgejo"; + }; + }; + + environment.persistence."/persistent" = { + directories = [ + { + directory = "/appdata/forgejo"; + user = "forgejo"; + mode = "0700"; + } + ]; + }; + + environment.systemPackages = + let + forgejo-cli = pkgs.writeShellScriptBin "forgejo-cli" '' + if [ $# -eq 0 ]; then + echo "No arguments supplied" + exit 1 + fi + sudo -u forgejo -- ${lib.getExe pkgs.forgejo} --config /appdata/forgejo/custom/conf/app.ini $@ + ''; + in + [ + forgejo-cli + ]; + + services.forgejo = { + enable = true; + stateDir = "/appdata/forgejo"; + lfs.enable = true; + + database = { + type = "postgres"; + passwordFile = secrets."forgejo/db_pass".path; + }; + + settings = { + repository = { + ENABLE_PUSH_CREATE_USER = true; + ENABLE_PUSH_CREATE_ORG = true; + }; + + server = { + DOMAIN = cfg.domain; + # You need to specify this to remove the port from URLs in the web UI. + ROOT_URL = "https://${cfg.domain}/"; + HTTP_PORT = 3000; + + START_SSH_SERVER = true; + SSH_PORT = 2222; + SSH_LISTEN_PORT = 2222; + BUILTIN_SSH_SERVER_USER = "git"; + }; + + service = { + REGISTER_EMAIL_CONFIRM = true; + DISABLE_REGISTRATION = true; + ENABLE_NOTIFY_MAIL = true; + }; + + admin.DISABLE_REGULAR_ORG_CREATION = true; + + actions = { + ENABLED = true; + DEFAULT_ACTIONS_URL = "github"; + }; + + mailer = { + ENABLED = true; + }; + }; + + secrets = { + mailer = { + SMTP_ADDR = secrets."forgejo/email_host".path; + SMTP_PORT = secrets."forgejo/email_port".path; + FROM = secrets."forgejo/email_from".path; + USER = secrets."forgejo/email_username".path; + PASSWD = secrets."forgejo/email_password".path; + }; + }; + }; + }; + }; +} diff --git a/secrets/nix-test.yaml b/secrets/nix-test.yaml index 17f609e..84a6e54 100644 --- a/secrets/nix-test.yaml +++ b/secrets/nix-test.yaml @@ -10,8 +10,16 @@ authentik: email_from: ENC[AES256_GCM,data:X6NP2i3uAZQFK7JdeviIMFhNPw==,iv:dwZFyzzzzFNTVfe1nhWebXrTolCa991p+vJUAOxFJf8=,tag:gClo9mZfaVFP35yZath0Nw==,type:str] email_username: ENC[AES256_GCM,data:c1lu5Tw6N6w96uUujSj1wHh7fQ==,iv:XX2iYXOzz8EhcZ75NlmLsasnZnCrihE9K17qS2nhAyI=,tag:qfhh3bB530IIsJwmjG20Lw==,type:str] email_password: ENC[AES256_GCM,data:2f/LN5q/5RRIzAc8ol9RByf+RrQ=,iv:gy/UvcKzpvC0r4nQFbTYta8alzTjPWhFWCjGIw/PnuU=,tag:LLOk7NMuQ3VZ2zA779A5dw==,type:str] +forgejo: + db_pass: ENC[AES256_GCM,data:xJ0Jh4Q0gr0zoTful8iprs7Ly+xifvsaR9GgUrgvmsVatA4Ad7laVo9bnj3fpEHm3hOtlpKalys=,iv:69dIKbyG8UOhI5537Yf14vLt5HLVQ6FIK5mGd2/KEIM=,tag:Ef1z297ens/aKAwIMYctWA==,type:str] + email_host: ENC[AES256_GCM,data:HDJjMSYAgbvdS6p4TD7L3B3pAmNq7Q==,iv:01kDFluA0yuqJCa57kopLw0i1/t83FQu/RjoyAl8d8w=,tag:OswWkJxwlDZvH7GjVKv0MA==,type:str] + email_port: ENC[AES256_GCM,data:WOKc,iv:c1oMvzUr8S6ciP/35f/8FjhFSyF3cJCoa2kKGccGuB4=,tag:pBDK6cCg1vAMV4KEcd7lhw==,type:str] + email_from: ENC[AES256_GCM,data:H/aOZlAvMlv1CpW5i1v5U6PO,iv:e7j2pzvRY2798O4bDDI0k/hoQhUxG+g44C85jgYBD2c=,tag:4WpzQdSAs1bS8Pqh2ZIm1w==,type:str] + email_username: ENC[AES256_GCM,data:TPq7n3ypd4sXcx5l+b4ngVu8,iv:s1ifRo9Ro8v8p+Gq1pJsWxz9A3oK6Rt9tA1Bfbs3fzQ=,tag:nN+yqVk2hBOcHqe0QiIGyw==,type:str] + email_password: ENC[AES256_GCM,data:nyiLr08pVqBYFoEasYvjwVMJL9I=,iv:Cf1JzGgnr5HzPtGG4a59WWoDm2z9Ksnz1Z/A/xK6/34=,tag:1y2mpQixkmjdPdyXEFUouQ==,type:str] postgres: authentik: ENC[AES256_GCM,data:45DJfPHXeGyT8KDty5Po68whOVSTbT+iAfBpJ/6dKy0EeaKLKq/w1A==,iv:CtmwN+9tKmsCcU46OvBME/urkAvjEtVBqfqgs8dkkCU=,tag:j+yZfVv62IhkgF7HRT6zLQ==,type:str] + forgejo: ENC[AES256_GCM,data:tL1XRh6taMU8sGGF4zE9V3pY4jUn3zeyumTcmen5cTmE9z1A2UVpC8f8ZkWnz+97k+OWIKzbqZs=,iv:B2V+n7u7B89fy07WvzMwXSFgZEuNpHAvdywHI6RIhaI=,tag:5WmIIH79BLPuh31DGq5CaA==,type:str] sops: kms: [] gcp_kms: [] @@ -45,8 +53,8 @@ sops: OHkvUTViMVZSUGFSeDN1ZDcxN3NtNzQK48qiEMcKbsrh8ZhnMD7lkhsy0JRMYiOU EtXwHxEzIXukStQ9kXazfHJJouuqv7mhx12tgv+QKvrfWxCJ5WvE2A== -----END AGE ENCRYPTED FILE----- - lastmodified: "2025-02-11T16:20:59Z" - mac: ENC[AES256_GCM,data:e1uqTmgVc60EHKEwsrcdh+qA2pA+Acy89DHEMCTN2eTR9hb9ya2FkEa6+X2ckgMQsngWGg/N+wAxR+wOyqLNuX1Rcb0ee3YxzaHxQZamTp09XL5IPooTNqfQdEiexPHBoJr+OtftkvsvhxmBUvh9+/VZpvnEVHwBcJAPF9KRrCI=,iv:66Uq37oID3XrRY+xcza2VNZCqhSKkAz6SJeJ3scfTmE=,tag:r6hua8+RfF99DtJsTALRpQ==,type:str] + lastmodified: "2025-02-16T11:32:08Z" + mac: ENC[AES256_GCM,data:gO1LQdr6HTMMH3czNhMjS9BS9fNyQbw/50KGiAcS97lWN840zYmKXe/n8cJUmBHPtQZVB9QfQTuC3uEEFvhOd0qlmCQaCso5gbyxlTRx3Q2yx/JcpZtktWaJLqsncVUMELavKy7yB0/Q8QnUdDz0Tfo1qotY2He8iyyZUTBkuDA=,iv:+hZg5EJZ8jy08LG3Of9fb1NkN/fbBhhSXh+rM7a9PU8=,tag:UjayBiZy7QV8Puzu3jPIFQ==,type:str] pgp: [] unencrypted_suffix: _unencrypted version: 3.9.2