{ config, lib, pkgs, ... }: { options.zpha.websites."gts.zaphyra.eu".enable = lib.mkEnableOption ""; config = lib.mkIf config.zpha.websites."gts.zaphyra.eu".enable { dns.zones."zaphyra.eu".subdomains."gts".CNAME = [ "${config.networking.fqdn}." ]; users = { users.gotosocial.uid = 818; groups.gotosocial.gid = 818; }; sops.secrets = { "restic/gotosocial/repositoryPassword" = { }; "restic/gotosocial/sshPrivateKey" = { }; "environments/gotosocial" = { restartUnits = [ "gotosocial.service" ]; }; }; systemd.tmpfiles.settings.gotosocial = { "/var/lib/gotosocial/storage".d = { inherit (config.common.services.gotosocial) user group; mode = "750"; age = "-"; }; }; common = { configure.persist.system.dirs = lib.singleton { inherit (config.common.services.gotosocial) user group; directory = config.common.services.gotosocial.stateDir; mode = "0755"; }; services.resticBackup.gotosocial = { enable = true; inherit (config.common.services.gotosocial) user; targets = [ "restic-target.fc9f.de" "isodon.fc9f.de" ]; sshKeyFile = config.sops.secrets."restic/gotosocial/sshPrivateKey".path; passwordFile = config.sops.secrets."restic/gotosocial/repositoryPassword".path; sqliteDatabases = [ (lib.mkIf ( config.common.services.gotosocial.settings.db-type == "sqlite" ) config.common.services.gotosocial.settings.db-address) ]; paths = [ (lib.mkIf ( config.common.services.gotosocial.settings.storage-backend == "local" ) config.common.services.gotosocial.settings.storage-local-base-path) "${config.common.services.gotosocial.stateDir}/backup.json" ]; runBeforeBackup = '' ${config.common.services.gotosocial.package}/bin/gotosocial --config-path /etc/gotosocial.yaml admin export --path ${config.common.services.gotosocial.stateDir}/backup.json ''; }; }; common.services.gotosocial = { enable = true; package = pkgs.zpha.gotosocial-unstable; inherit (config.services.nginx) group; environmentFile = config.sops.secrets."environments/gotosocial".path; settings = { protocol = "https"; bind-address = "::1"; port = 8085; trusted-proxies = [ "::1/128" "172.17.0.0/24" ]; db-type = "sqlite"; db-address = "${config.common.services.gotosocial.stateDir}/database.sqlite"; storage-backend = "local"; storage-local-base-path = "${config.common.services.gotosocial.stateDir}/storage"; host = "gts.zaphyra.eu"; account-domain = "zaphyra.eu"; 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 = [ "en" "de" ]; media-emoji-local-max-size = "100KiB"; media-local-max-size = "50MiB"; media-remote-max-size = "50MiB"; media-remote-cache-duration = "3 days"; media-cleanup-cron = "30 23 * * *"; smtp-host = "morio.infra.zaphyra.eu"; smtp-port = 587; smtp-username = "gts@zaphyra.eu"; smtp-from = "gts@zaphyra.eu"; advanced-rate-limit-requests = 3000; }; }; services.nginx = { appendHttpConfig = '' proxy_cache_path /var/cache/nginx keys_zone=gotosocial_ap_public_responses:10m inactive=1w; ''; virtualHosts = { "${config.common.services.gotosocial.settings.host}" = { useACMEHost = lib.mkDefault config.networking.fqdn; forceSSL = lib.mkDefault true; kTLS = lib.mkDefault true; locations = { "/" = { proxyPass = "http://[${toString config.common.services.gotosocial.settings.bind-address}]:${toString config.common.services.gotosocial.settings.port}"; proxyWebsockets = true; }; "/client/" = { index = "index.html"; alias = "${ pkgs.zpha.phanpy.override { clientName = "zaphyra's fedi"; website = "https://gts.zaphyra.eu/client/"; defaultInstance = "gts.zaphyra.eu"; } }/"; }; "~ /.well-known/(webfinger|host-meta)$" = { proxyPass = "http://[${toString config.common.services.gotosocial.settings.bind-address}]:${toString config.common.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.common.services.gotosocial.settings.bind-address}]:${toString config.common.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.common.services.gotosocial.package}/share/gotosocial/web/assets/; autoindex off; expires max; add_header Cache-Control "public, immutable"; ''; }; }; } // ( if ( config.common.services.gotosocial.settings.account-domain != config.common.services.gotosocial.settings.host ) then { "${config.common.services.gotosocial.settings.account-domain}" = { locations = { "= /.well-known/host-meta".extraConfig = "return 301 https://${config.common.services.gotosocial.settings.host}$request_uri;"; "= /.well-known/webfinger".extraConfig = "return 301 https://${config.common.services.gotosocial.settings.host}$request_uri;"; "= /.well-known/nodeinfo".extraConfig = "return 301 https://${config.common.services.gotosocial.settings.host}$request_uri;"; }; }; } else { } ); }; }; }