commit b64f1b7d24d954e0014dcda36e3be85353146a78
parent 31b88bb707e3581bd4a48d6ee76feafeff29413a
Author: Katja (zaphyra) <git@ctu.cx>
Date: Fri, 6 Jun 2025 21:21:40 +0200
parent 31b88bb707e3581bd4a48d6ee76feafeff29413a
Author: Katja (zaphyra) <git@ctu.cx>
Date: Fri, 6 Jun 2025 21:21:40 +0200
config/nixos/modules/websites: add `fedi.home.ctu.cx` (and enable on host `polaris`)
3 files changed, 200 insertions(+), 2 deletions(-)
A
|
193
+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
diff --git a/config/nixos/modules/websites/fedi.home.ctu.cx.nix b/config/nixos/modules/websites/fedi.home.ctu.cx.nix @@ -0,0 +1,193 @@ +{ + name, + povSelf, + hostConfig, + config, + pkgs, + lib, + ... +}: + +let + inherit (lib) types; + cfg = lib.getAttrFromPath povSelf config; + cfgWebsites = lib.getAttrFromPath (lib.remove name povSelf) config; + +in +{ + + options = { + enable = { + type = types.bool; + default = false; + }; + domain = { + type = types.str; + default = "ctu.cx"; + }; + subdomain = { + type = types.str; + default = "fedi.home"; + }; + }; + + config = lib.mkIf cfg.enable { + dns.zones."${cfg.domain}".subdomains."${cfg.subdomain}".CNAME = [ "${config.networking.fqdn}." ]; + + sops.secrets = { + "resticPasswords/gotosocial" = { }; + }; + + systemd.tmpfiles.settings.gotosocial = { + "/var/lib/gotosocial/storage".d = { + user = config.modules.services.gotosocial.user; + group = config.modules.services.gotosocial.group; + mode = "750"; + age = "-"; + }; + }; + + modules.services = { + resticBackup.paths = { + gotosocial = { + enable = true; + user = config.modules.services.gotosocial.user; + passwordFile = config.sops.secrets."resticPasswords/gotosocial".path; + sqliteDatabases = [ + (lib.mkIf ( + config.modules.services.gotosocial.settings.db-type == "sqlite" + ) config.modules.services.gotosocial.settings.db-address) + ]; + paths = [ + (lib.mkIf ( + config.modules.services.gotosocial.settings.storage-backend == "local" + ) config.modules.services.gotosocial.settings.storage-local-base-path) + "${config.modules.services.gotosocial.stateDir}/backup.json" + ]; + runBeforeBackup = ''${pkgs.gotosocial}/bin/gotosocial --config-path /etc/gotosocial.yaml admin export --path ${config.modules.services.gotosocial.stateDir}/backup.json''; + }; + }; + gotosocial = { + enable = true; + group = config.services.nginx.group; + settings = { + protocol = lib.mkDefault "https"; + + bind-address = lib.mkDefault "[::1]"; + port = lib.mkDefault 8085; + + trusted-proxies = lib.mkDefault [ + "::1/128" + "172.17.0.0/24" + ]; + + db-type = lib.mkDefault "sqlite"; + db-address = lib.mkDefault "${config.modules.services.gotosocial.stateDir}/db.sqlite"; + + storage-backend = lib.mkDefault "local"; + storage-local-base-path = "${config.modules.services.gotosocial.stateDir}/storage"; + + host = "${cfg.subdomain}.${cfg.domain}"; + account-domain = cfg.domain; + + landing-page-user = "katja"; + + accounts-allow-custom-css = true; + accounts-registration-open = false; + + instance-expose-peers = true; + instance-expose-suspended = true; + instance-expose-suspended-web = true; + + instance-languages = [ + "de" + "en-us" + ]; + + media-local-max-size = "50MiB"; + media-remote-max-size = "50MiB"; + + media-remote-cache-days = 3; + media-cleanup-from = "01:00"; + }; + }; + }; + + services.nginx = { + appendHttpConfig = '' + proxy_cache_path /var/cache/nginx keys_zone=gotosocial_ap_public_responses:10m inactive=1w; + ''; + virtualHosts = + { + "${config.modules.services.gotosocial.settings.host}" = { + useACMEHost = lib.mkDefault "${config.networking.fqdn}"; + forceSSL = lib.mkDefault true; + kTLS = lib.mkDefault true; + locations = { + "/" = { + proxyPass = "http://${toString config.modules.services.gotosocial.settings.bind-address}:${toString config.modules.services.gotosocial.settings.port}"; + proxyWebsockets = true; + }; + + "~ /.well-known/(webfinger|host-meta)$" = { + proxyPass = "http://${toString config.modules.services.gotosocial.settings.bind-address}:${toString config.modules.services.gotosocial.settings.port}"; + extraConfig = '' + proxy_cache gotosocial_ap_public_responses; + proxy_cache_background_update on; + proxy_cache_key $scheme://$host$uri$is_args$query_string; + proxy_cache_valid 200 10m; + proxy_cache_use_stale error timeout updating http_500 http_502 http_503 http_504 http_429; + proxy_cache_lock on; + add_header X-Cache-Status $upstream_cache_status; + ''; + }; + + "~ ^\/users\/(?:[a-z0-9_\.]+)\/main-key$" = { + proxyPass = "http://${toString config.modules.services.gotosocial.settings.bind-address}:${toString config.modules.services.gotosocial.settings.port}"; + extraConfig = '' + proxy_cache gotosocial_ap_public_responses; + proxy_cache_background_update on; + proxy_cache_key $scheme://$host$uri; + proxy_cache_valid 200 604800s; + proxy_cache_use_stale error timeout updating http_500 http_502 http_503 http_504 http_429; + proxy_cache_lock on; + + add_header X-Cache-Status $upstream_cache_status; + ''; + }; + + "/assets/".extraConfig = '' + alias ${config.modules.services.gotosocial.package}/share/web/assets/; + autoindex off; + expires max; + add_header Cache-Control "public, immutable"; + ''; + }; + }; + } + // ( + if + ( + config.modules.services.gotosocial.settings.account-domain + != config.modules.services.gotosocial.settings.host + ) + then + { + "${config.modules.services.gotosocial.settings.account-domain}" = { + locations = { + "= /.well-known/host-meta".extraConfig = + "return 301 https://${config.modules.services.gotosocial.settings.host}$request_uri;"; + "= /.well-known/webfinger".extraConfig = + "return 301 https://${config.modules.services.gotosocial.settings.host}$request_uri;"; + "= /.well-known/nodeinfo".extraConfig = + "return 301 https://${config.modules.services.gotosocial.settings.host}$request_uri;"; + }; + }; + } + else + { } + ); + }; + }; + +}
diff --git a/hosts/polaris/default.nix b/hosts/polaris/default.nix @@ -79,6 +79,10 @@ }; }; + websites = { + "fedi.home.ctu.cx".enable = true; + }; + users.zaphyra.enable = true; };
diff --git a/secrets/polaris.yaml b/secrets/polaris.yaml @@ -9,6 +9,7 @@ environments: influxdb2: ENC[AES256_GCM,data:GVEs92BPKe8Lv4VxVBnbjTTVHszVCZHmd/gTw/K4UscX4efwjldknLPOqAEPNF7SdoEEbX17dSA0BL8Gj68j4rhTPJMGluWOprfDAZ+gMpEglfbfU4P2J0WgrbgLZDj53kBx95NsysVWGaR14jyff0S5Ay5YgSo=,iv:FAjaA/VsW1KNRbsoyv79jW4ooRaYMUs7SiWJ1VQBlqU=,tag:iC+wAFXR8EcKd67OL+lIIw==,type:str] resticPasswords: influxdb2: ENC[AES256_GCM,data:OBGzj5IcuM7bvb2k/wg3qwisA5TC9qMNWU4KDP2OEUs=,iv:DqTNEVQDpmRB6MOKvyKJ6YuWdKpIIt1q6yfeTaFSiZI=,tag:rTPtLkP0d4mVb0fvSHIzlw==,type:str] + gotosocial: ENC[AES256_GCM,data:8bL/PtcqOhskUWFxvGAPURl2OIOdr1AgwvIZcpB4mmk=,iv:/Ft30MuCx7l+MmIEGIA+vRohG73Zkhtg8O8kHLbkpBE=,tag:3X9RfGR+qMogW9uL6Ki4Rw==,type:str] sops: age: - recipient: age1qyqy5we7zua06ppj654rgd6t7kyw3gem6hnexna98j60klyus4zq68cjlz @@ -20,8 +21,8 @@ sops: SUhEaGg3dE9HTnJZVXU5cXZ1YkVVQTgKreIDmLNlNfHNW5XGDJdAN9WIHOQqKKLP yPTbVRLiDdAejAOTA89fR6Vz1hAGtoPQuQoIFQXBdd8TLmp2C5hH5A== -----END AGE ENCRYPTED FILE----- - lastmodified: "2025-06-03T13:50:14Z" - mac: ENC[AES256_GCM,data:CPJfG8ICl+Yed2rLoTYZCBjhagpocmVfglY8NRYvjUl0bMUU+L/kjt8jcUcDb3t9/Z3RHMhazx6H2KeEdFvQyj3tMozd41stEs08jn4yL8qHCamNUhPfJVKY7lDi8ocNObcB9oE6Db3LLKpsSSFEmvg7Sssy7M4XklMM2Z7Mlbs=,iv:H5u4xmUp53enQGN74GyTSM0//t1l+Kcg+S1AeNL9ykg=,tag:cLgOHf1fbKS5l0VBR0q9MQ==,type:str] + lastmodified: "2025-06-07T09:58:47Z" + mac: ENC[AES256_GCM,data:qS9JNAlA45AjBtaTW4DZQq/kl6GHz7pr8FXe+GUjQMbZNFy5ZPVTEEvxBQ93SYV7XN3XpjKfzLLbus7V+0gMHDEcz2Q7jEFpP7rzdrNbp0w0NEeOV7XFKnk35drQEcJ0+khcrMvfreWLHfCKaTI2x01ag/8tkBuFg8Wqr9tFCmU=,iv:XMY45Ax7rRnotd5be2ThfVcjZT2qU70sC6z0w1/NwVU=,tag:puZI/8HBQ0eG0IxgGIPihA==,type:str] pgp: - created_at: "2025-06-02T17:31:26Z" enc: |-