{ pkgs, ... }: let nodejs = pkgs.unstable.nodejs_20; nodePackages = (pkgs.nodePackages.override { nodejs = nodejs; }); in { services.postgresql = { enable = true; package = pkgs.postgresql_15; ensureUsers = [ { name = "jaina"; } { name = "misskey"; ensureDBOwnership = true; } { name = "postgres"; } ]; ensureDatabases = [ "misskey" ]; identMap = '' # ArbitraryMapName systemUser DBUser superuser_map root postgres superuser_map postgres postgres # Let other names login as themselves superuser_map /^(.*)$ \1 ''; }; services.redis.servers.misskey = { port = 6379; enable = true; openFirewall = false; requirePassFile = "/etc/nixos-secrets/redis-pass"; }; # services.meilisearch = { # enable = true; # maxIndexSize = "20Gb"; # environment = "production"; # masterKeyEnvironmentFile = "/etc/nixos-secrets/meili-key"; # }; security.acme = { acceptTerms = true; defaults.email = "admin+acme@heartles.xyz"; certs."egirls.gay" = { domain = "egirls.gay"; dnsProvider = "namecheap"; credentialsFile = "/etc/nixos-secrets/namecheap-acme"; group = "nginx"; }; certs."STAR.egirls.gay" = { domain = "*.egirls.gay"; dnsProvider = "namecheap"; credentialsFile = "/etc/nixos-secrets/namecheap-acme"; group = "nginx"; }; }; networking.firewall.allowedTCPPorts = [ 80 443 ]; services.nginx = let listen = [ { port = 443; addr = "0.0.0.0"; ssl = true; } { port = 80; addr = "0.0.0.0"; } { port = 443; addr = "[::]"; ssl = true; } { port = 80; addr = "[::]"; } ]; in { enable = true; recommendedProxySettings = true; package = pkgs.openresty; upstreams."misskey".extraConfig = '' server unix:/var/run/misskey/misskey.sock; ''; proxyCachePath."egirls_media_cache" = { enable = true; maxSize = "1g"; inactive = "10m"; keysZoneName = "egirls_media_cache"; }; virtualHosts."media.egirls.gay" = { inherit listen; forceSSL = true; useACMEHost = "STAR.egirls.gay"; extraConfig = '' client_max_body_size 1m; proxy_cache egirls_media_cache; proxy_cache_valid 200 10m; proxy_cache_lock on; proxy_ignore_headers X-Accel-Expires Expires Cache-Control; proxy_hide_header X-Amz-ID-2; proxy_hide_header X-Amz-Request-ID; proxy_hide_header X-Wasabi-CM-Reference-ID; proxy_hide_header Set-Cookie; proxy_ignore_headers Set-Cookie; ''; locations."/".extraConfig = '' return 404; ''; locations."/misskey/".extraConfig = '' proxy_http_version 1.1; include /etc/nixos-secrets/s3-access-nginx.conf; set $s3_bucket 'egirls-gay-misskey'; set $path_full '/$s3_bucket$request_uri'; set_by_lua $now "return ngx.http_time(ngx.time())"; set $signature_string "GET\n\n\n\nx-amz-date:''${now}\n$path_full"; set_hmac_sha1 $s3_signature $s3_secret $signature_string; set_encode_base64 $s3_signature_b64 $s3_signature; proxy_set_header x-amz-date $now; proxy_set_header Authorization "AWS $s3_access:$s3_signature_b64"; proxy_ssl_session_reuse on; rewrite .* $path_full break; proxy_pass https://s3.us-west-1.wasabisys.com; ''; locations."/localfiles/" = { root = "/srv/www/localfiles"; tryFiles = "$uri =404"; }; }; virtualHosts."egirls.gay" = { inherit listen; forceSSL = true; useACMEHost = "egirls.gay"; locations."/" = { proxyWebsockets = true; proxyPass = "http://misskey"; extraConfig = '' proxy_cache off; ''; }; locations."/api/drive/files/create" = { proxyWebsockets = true; proxyPass = "http://misskey"; extraConfig = '' # increase max size and don't buffer file uploads client_max_body_size 2g; proxy_request_buffering off; proxy_cache off; ''; }; locations."/.well-known/matrix/server".extraConfig = '' add_header Content-Type application/json; add_header Access-Control-Allow-Origin '*'; return 200 '{"m.server":"synapse.egirls.gay"}'; ''; locations."/.well-known/matrix/client".extraConfig = '' add_header Content-Type application/json; add_header Access-Control-Allow-Origin '*'; return 200 '{"m.homeserver":{"base_url":"https://synapse.egirls.gay"}}'; ''; }; }; users.groups.misskey = { members = [ "jaina" ]; }; users.users.misskey = { isSystemUser = true; group = "misskey"; createHome = true; }; # todo: figure out how to get misskey to build in nix instead of requiring a manual build process # # pnpm2nix does not work due to misskey using workspaces environment.systemPackages = [ nodejs nodePackages.pnpm pkgs.cypress pkgs.pkg-config pkgs.vips ]; environment.sessionVariables = { CYPRESS_INSTALL_BINARY = "0"; CYPRESS_RUN_BINARY = "${pkgs.cypress}/bin/Cypress"; }; systemd.services.misskey = { enable = true; description = "Misskey daemon"; #path = [ nodejs nodePackages.pnpm pkgs.coreutils pkgs.cypress pkgs.pkg-config pkgs.vips ]; serviceConfig = { Restart = "always"; StandardOutput = "syslog"; StandardError = "syslog"; Environment = [ "NODE_ENV=production" # TODO Fix this "PATH=/run/wrappers/bin:/var/empty/.nix-profile/bin:/nix/profile/bin:/var/empty/.local/state/nix/profile/bin:/etc/profiles/per-user/misskey/bin:/nix/var/nix/profiles/default/bin:/run/current-system/sw/bin" ]; WorkingDirectory = "/srv/misskey"; User = "misskey"; ExecStart = "${nodePackages.pnpm}/bin/pnpm start"; RuntimeDirectory = "misskey"; }; wantedBy = [ "multi-user.target" ]; }; }