diff --git a/flake.nix b/flake.nix index 71148168..3f30a1ec 100644 --- a/flake.nix +++ b/flake.nix @@ -262,6 +262,14 @@ packages = import ./packages.nix { inherit hostRegistry inputs lib microvm self; }; nixosConfigurations = { + activity-relay = nixosSystem' { + modules = [ + self.nixosModules.microvm + ./modules/activity-relay.nix + ./hosts/activity-relay + ]; + }; + auth = nixosSystem' { modules = [ self.nixosModules.microvm diff --git a/hosts/activity-relay/default.nix b/hosts/activity-relay/default.nix new file mode 100644 index 00000000..719decd3 --- /dev/null +++ b/hosts/activity-relay/default.nix @@ -0,0 +1,43 @@ +{ config, pkgs, ... }: +{ + c3d2 = { + deployment.server = "server10"; + hq.statistics.enable = true; + }; + + microvm = { + mem = 512; + vcpu = 8; + }; + + networking.hostName = "activity-relay"; + services.journald.extraConfig = '' + Storage=volatile + ''; + + services = { + activity-relay = { + enable = true; + jobConcurrency = config.microvm.vcpu; + relay = { + bind = "127.0.0.1:8080"; + domain = "activity-relay.serv.zentralwerk.org"; + }; + }; + + redis = { + enable = true; + }; + + nginx = { + enable = true; + virtualHosts."activity-relay.serv.zentralwerk.org" = { + forceSSL = true; + enableACME = true; + locations."/".proxyPass = "http://${config.services.activity-relay.relay.bind}/"; + }; + }; + }; + + system.stateVersion = "23.05"; +} diff --git a/modules/activity-relay.nix b/modules/activity-relay.nix new file mode 100644 index 00000000..06544674 --- /dev/null +++ b/modules/activity-relay.nix @@ -0,0 +1,153 @@ +{ lib, config, pkgs, ... }: + +let + cfg = config.services.activity-relay; + + configFile = pkgs.writeText "activity-relay.json" ( + builtins.toJSON ({ + ACTOR_PEM = cfg.actorPem.path; + REDIS_URL = cfg.redisUrl; + RELAY_BIND = cfg.relay.bind; + RELAY_SERVICENAME = cfg.relay.serviceName; + RELAY_DOMAIN = cfg.relay.domain; + RELAY_SUMMARY = cfg.relay.summary; + JOB_CONCURRENCY = cfg.jobConcurrency; + } // lib.optionalAttrs (cfg.relay.icon != null) { + RELAY_ICON = cfg.relay.icon; + } // lib.optionalAttrs (cfg.relay.image != null) { + RELAY_IMAGE = cfg.relay.image; + })); +in +{ + options.services.activity-relay = { + enable = lib.mkEnableOption "Activity-Relay ActivityPub relay server"; + + package = lib.mkOption { + type = lib.types.package; + default = pkgs.activity-relay; + }; + + user = lib.mkOption { + type = lib.types.str; + default = "relay"; + }; + group = lib.mkOption { + type = lib.types.str; + default = "relay"; + }; + + actorPem.path = lib.mkOption { + type = lib.types.str; + default = "${config.users.users.${cfg.user}.home}/actor.pem"; + }; + actorPem.generate = lib.mkOption { + type = lib.types.bool; + default = true; + }; + + redisUrl = lib.mkOption { + type = lib.types.str; + default = "redis://127.0.0.1:6379"; + }; + + relay = { + bind = lib.mkOption { + type = lib.types.str; + default = "0.0.0.0:8080"; + }; + domain = lib.mkOption { + type = lib.types.str; + }; + serviceName = lib.mkOption { + type = lib.types.str; + default = "NixOS Activity-Relay"; + }; + summary = lib.mkOption { + type = lib.types.str; + default = ""; + }; + icon = lib.mkOption { + type = with lib.types; nullOr str; + default = null; + }; + image = lib.mkOption { + type = with lib.types; nullOr str; + default = null; + }; + }; + + jobConcurrency = lib.mkOption { + type = lib.types.int; + default = 50; + }; + }; + + config = lib.mkIf cfg.enable { + users = { + users.${cfg.user} = { + isSystemUser = true; + inherit (cfg) group; + home = "/var/lib/activity-relay"; + }; + groups.${cfg.group} = {}; + }; + + systemd.services = { + relay-api = { + description = "Activity-Relay server"; + after = [ "network.target" ]; + wantedBy = [ "multi-user.target" ]; + serviceConfig = { + User = cfg.user; + Group = cfg.group; + StateDirectory = "activity-relay"; + CapabilityBoundingSet = ""; + PrivateDevices = true; + PrivateUsers = true; + ProtectHome = true; + ProtectKernelLogs = true; + ProtectProc = "invisible"; + RestrictAddressFamilies = [ "AF_UNIX" "AF_INET" "AF_INET6" ]; + RestrictNamespaces = true; + SystemCallArchitectures = "native"; + # SystemCallFilter = [ "@system-service" "~@privileged" "~@resources" ]; + Restart = lib.mkDefault "always"; + RestartSec = 10; + }; + script = '' + ${lib.optionalString cfg.actorPem.generate '' + if ! [ -e "${cfg.actorPem.path}" ]; then + ${lib.getExe pkgs.openssl} genrsa -traditional > "${cfg.actorPem.path}" + fi + ''} + + exec ${lib.getExe cfg.package} -c ${configFile} -v server + ''; + }; + + relay-worker = { + description = "Activity-Relay worker"; + after = [ "network.target" "relay-api.service" ]; + wantedBy = [ "multi-user.target" ]; + serviceConfig = { + User = cfg.user; + Group = cfg.group; + StateDirectory = "activity-relay"; + CapabilityBoundingSet = ""; + PrivateDevices = true; + PrivateUsers = true; + ProtectHome = true; + ProtectKernelLogs = true; + ProtectProc = "invisible"; + RestrictAddressFamilies = [ "AF_UNIX" "AF_INET" "AF_INET6" ]; + RestrictNamespaces = true; + SystemCallArchitectures = "native"; + # SystemCallFilter = [ "@system-service" "~@privileged" "~@resources" ]; + Restart = lib.mkDefault "always"; + RestartSec = 10; + ExecStart = "${lib.getExe cfg.package} -c ${configFile} -v worker"; + }; + }; + }; + }; +} diff --git a/overlays/activity-relay.nix b/overlays/activity-relay.nix new file mode 100644 index 00000000..a482fba6 --- /dev/null +++ b/overlays/activity-relay.nix @@ -0,0 +1,27 @@ +{ lib, buildGoModule, fetchFromGitHub +}: + +buildGoModule rec { + pname = "activity-relay"; + version = "2.0.4"; + + src = fetchFromGitHub { + owner = "yukimochi"; + repo = pname; + rev = "v${version}"; + hash = "sha256-0mZrkOrlg4AZFD8K6bcLPx7Xty7mRqjlxStwxXna70c="; + }; + + vendorHash = "sha256-EHfRDFzfoi9YiKoeRasWSiyqT1HrIK8gIPadpyNYgbU="; + + # tests require internet access + doCheck = false; + + meta = with lib; { + mainProgram = "Activity-Relay"; + description = "Yet another powerful customizable ActivityPub relay server written in Go."; + homepage = "https://github.com/yukimochi/Activity-Relay"; + license = licenses.agpl3; + maintainers = with maintainers; [ astro ]; + }; +} diff --git a/overlays/default.nix b/overlays/default.nix index 19253146..5fe827bc 100644 --- a/overlays/default.nix +++ b/overlays/default.nix @@ -6,6 +6,8 @@ final: prev: with final; { + activity-relay = callPackage ./activity-relay.nix { }; + allcolors = callPackage ./allcolors.nix { }; inherit (bevy-julia.packages.${system}) bevy_julia;