Merge pull request #232862 from misuzu/gotosocial-init

authored by

Sandro and committed by
GitHub
9183a72d 6bba553f

+335
+2
nixos/doc/manual/release-notes/rl-2311.section.md
··· 14 14 15 15 - [river](https://github.com/riverwm/river), A dynamic tiling wayland compositor. Available as [programs.river](#opt-programs.river.enable). 16 16 17 + - [GoToSocial](https://gotosocial.org/), an ActivityPub social network server, written in Golang. Available as [services.gotosocial](#opt-services.gotosocial.enable). 18 + 17 19 - [sitespeed-io](https://sitespeed.io), a tool that can generate metrics (timings, diagnostics) for websites. Available as [services.sitespeed-io](#opt-services.sitespeed-io.enable). 18 20 19 21 ## Backward Incompatibilities {#sec-release-23.11-incompatibilities}
+1
nixos/modules/module-list.nix
··· 1190 1190 ./services/web-apps/galene.nix 1191 1191 ./services/web-apps/gerrit.nix 1192 1192 ./services/web-apps/gotify-server.nix 1193 + ./services/web-apps/gotosocial.nix 1193 1194 ./services/web-apps/grocy.nix 1194 1195 ./services/web-apps/pixelfed.nix 1195 1196 ./services/web-apps/healthchecks.nix
+64
nixos/modules/services/web-apps/gotosocial.md
··· 1 + # GoToSocial {#module-services-gotosocial} 2 + 3 + [GoToSocial](https://gotosocial.org/) is an ActivityPub social network server, written in Golang. 4 + 5 + ## Service configuration {#modules-services-gotosocial-service-configuration} 6 + 7 + The following configuration sets up the PostgreSQL as database backend and binds 8 + GoToSocial to `127.0.0.1:8080`, expecting to be run behind a HTTP proxy on `gotosocial.example.com`. 9 + 10 + ```nix 11 + services.gotosocial = { 12 + enable = true; 13 + setupPostgresqlDB = true; 14 + settings = { 15 + application-name = "My GoToSocial"; 16 + host = "gotosocial.example.com"; 17 + protocol = "https"; 18 + bind-address = "127.0.0.1"; 19 + port = 8080; 20 + }; 21 + }; 22 + ``` 23 + 24 + Please refer to the [GoToSocial Documentation](https://docs.gotosocial.org/en/latest/configuration/general/) 25 + for additional configuration options. 26 + 27 + ## Proxy configuration {#modules-services-gotosocial-proxy-configuration} 28 + 29 + Although it is possible to expose GoToSocial directly, it is common practice to operate it behind an 30 + HTTP reverse proxy such as nginx. 31 + 32 + ```nix 33 + networking.firewall.allowedTCPPorts = [ 80 443 ]; 34 + services.nginx = { 35 + enable = true; 36 + clientMaxBodySize = "40M"; 37 + virtualHosts = with config.services.gotosocial.settings; { 38 + "${host}" = { 39 + enableACME = true; 40 + forceSSL = true; 41 + locations = { 42 + "/" = { 43 + recommendedProxySettings = true; 44 + proxyWebsockets = true; 45 + proxyPass = "http://${bind-address}:${toString port}"; 46 + }; 47 + }; 48 + }; 49 + }; 50 + }; 51 + ``` 52 + 53 + Please refer to [](#module-security-acme) for details on how to provision an SSL/TLS certificate. 54 + 55 + ## User management {#modules-services-gotosocial-user-management} 56 + 57 + After the GoToSocial service is running, the `gotosocial-admin` utility can be used to manage users. In particular an 58 + administrative user can be created with 59 + 60 + ```ShellSession 61 + $ sudo gotosocial-admin account create --username <nickname> --email <email> --password <password> 62 + $ sudo gotosocial-admin account confirm --username <nickname> 63 + $ sudo gotosocial-admin account promote --username <nickname> 64 + ```
+173
nixos/modules/services/web-apps/gotosocial.nix
··· 1 + { config, lib, pkgs, ... }: 2 + let 3 + cfg = config.services.gotosocial; 4 + settingsFormat = pkgs.formats.yaml { }; 5 + configFile = settingsFormat.generate "config.yml" cfg.settings; 6 + defaultSettings = { 7 + application-name = "gotosocial"; 8 + 9 + protocol = "https"; 10 + 11 + bind-address = "127.0.0.1"; 12 + port = 8080; 13 + 14 + storage-local-base-path = "/var/lib/gotosocial/storage"; 15 + 16 + db-type = "sqlite"; 17 + db-address = "/var/lib/gotosocial/database.sqlite"; 18 + }; 19 + gotosocial-admin = pkgs.writeShellScriptBin "gotosocial-admin" '' 20 + exec systemd-run \ 21 + -u gotosocial-admin.service \ 22 + -p Group=gotosocial \ 23 + -p User=gotosocial \ 24 + -q -t -G --wait --service-type=exec \ 25 + ${cfg.package}/bin/gotosocial --config-path ${configFile} admin "$@" 26 + ''; 27 + in 28 + { 29 + meta.doc = ./gotosocial.md; 30 + meta.maintainers = with lib.maintainers; [ misuzu ]; 31 + 32 + options.services.gotosocial = { 33 + enable = lib.mkEnableOption (lib.mdDoc "ActivityPub social network server"); 34 + 35 + package = lib.mkPackageOptionMD pkgs "gotosocial" { }; 36 + 37 + openFirewall = lib.mkOption { 38 + type = lib.types.bool; 39 + default = false; 40 + description = lib.mdDoc '' 41 + Open the configured port in the firewall. 42 + Using a reverse proxy instead is highly recommended. 43 + ''; 44 + }; 45 + 46 + setupPostgresqlDB = lib.mkOption { 47 + type = lib.types.bool; 48 + default = false; 49 + description = lib.mdDoc '' 50 + Whether to setup a local postgres database and populate the 51 + `db-type` fields in `services.gotosocial.settings`. 52 + ''; 53 + }; 54 + 55 + settings = lib.mkOption { 56 + type = settingsFormat.type; 57 + default = defaultSettings; 58 + example = { 59 + application-name = "My GoToSocial"; 60 + host = "gotosocial.example.com"; 61 + }; 62 + description = lib.mdDoc '' 63 + Contents of the GoToSocial YAML config. 64 + 65 + Please refer to the 66 + [documentation](https://docs.gotosocial.org/en/latest/configuration/) 67 + and 68 + [example config](https://github.com/superseriousbusiness/gotosocial/blob/main/example/config.yaml). 69 + 70 + Please note that the `host` option cannot be changed later so it is important to configure this correctly before you start GoToSocial. 71 + ''; 72 + }; 73 + 74 + environmentFile = lib.mkOption { 75 + type = lib.types.nullOr lib.types.path; 76 + description = lib.mdDoc '' 77 + File path containing environment variables for configuring the GoToSocial service 78 + in the format of an EnvironmentFile as described by systemd.exec(5). 79 + 80 + This option could be used to pass sensitive configuration to the GoToSocial daemon. 81 + 82 + Please refer to the Environment Variables section in the 83 + [documentation](https://docs.gotosocial.org/en/latest/configuration/). 84 + ''; 85 + default = null; 86 + example = "/root/nixos/secrets/gotosocial.env"; 87 + }; 88 + 89 + }; 90 + 91 + config = lib.mkIf cfg.enable { 92 + assertions = [ 93 + { 94 + assertion = cfg.settings.host or null != null; 95 + message = '' 96 + You have to define a hostname for GoToSocial (`services.gotosocial.settings.host`), it cannot be changed later without starting over! 97 + ''; 98 + } 99 + ]; 100 + 101 + services.gotosocial.settings = (lib.mapAttrs (name: lib.mkDefault) ( 102 + defaultSettings // { 103 + web-asset-base-dir = "${cfg.package}/share/gotosocial/web/assets/"; 104 + web-template-base-dir = "${cfg.package}/share/gotosocial/web/template/"; 105 + } 106 + )) // (lib.optionalAttrs cfg.setupPostgresqlDB { 107 + db-type = "postgres"; 108 + db-address = "/run/postgresql"; 109 + db-database = "gotosocial"; 110 + db-user = "gotosocial"; 111 + }); 112 + 113 + environment.systemPackages = [ gotosocial-admin ]; 114 + 115 + users.groups.gotosocial = { }; 116 + users.users.gotosocial = { 117 + group = "gotosocial"; 118 + isSystemUser = true; 119 + }; 120 + 121 + networking.firewall = lib.mkIf cfg.openFirewall { 122 + allowedTCPPorts = [ cfg.settings.port ]; 123 + }; 124 + 125 + services.postgresql = lib.mkIf cfg.setupPostgresqlDB { 126 + enable = true; 127 + ensureDatabases = [ "gotosocial" ]; 128 + ensureUsers = [ 129 + { 130 + name = "gotosocial"; 131 + ensurePermissions = { 132 + "DATABASE gotosocial" = "ALL PRIVILEGES"; 133 + }; 134 + } 135 + ]; 136 + }; 137 + 138 + systemd.services.gotosocial = { 139 + description = "ActivityPub social network server"; 140 + wantedBy = [ "multi-user.target" ]; 141 + after = [ "network.target" ] 142 + ++ lib.optional cfg.setupPostgresqlDB "postgresql.service"; 143 + requires = lib.optional cfg.setupPostgresqlDB "postgresql.service"; 144 + restartTriggers = [ configFile ]; 145 + 146 + serviceConfig = { 147 + EnvironmentFile = lib.mkIf (cfg.environmentFile != null) cfg.environmentFile; 148 + ExecStart = "${cfg.package}/bin/gotosocial --config-path ${configFile} server start"; 149 + Restart = "on-failure"; 150 + Group = "gotosocial"; 151 + User = "gotosocial"; 152 + StateDirectory = "gotosocial"; 153 + WorkingDirectory = "/var/lib/gotosocial"; 154 + 155 + # Security options: 156 + # Based on https://github.com/superseriousbusiness/gotosocial/blob/v0.8.1/example/gotosocial.service 157 + AmbientCapabilities = lib.optional (cfg.settings.port < 1024) "CAP_NET_BIND_SERVICE"; 158 + NoNewPrivileges = true; 159 + PrivateTmp = true; 160 + PrivateDevices = true; 161 + RestrictAddressFamilies = "AF_UNIX AF_INET AF_INET6"; 162 + RestrictNamespaces = true; 163 + RestrictRealtime = true; 164 + DevicePolicy = "closed"; 165 + ProtectSystem = "full"; 166 + ProtectControlGroups = true; 167 + ProtectKernelModules = true; 168 + ProtectKernelTunables = true; 169 + LockPersonality = true; 170 + }; 171 + }; 172 + }; 173 + }
+1
nixos/tests/all-tests.nix
··· 306 306 gonic = handleTest ./gonic.nix {}; 307 307 google-oslogin = handleTest ./google-oslogin {}; 308 308 gotify-server = handleTest ./gotify-server.nix {}; 309 + gotosocial = runTest ./web-apps/gotosocial.nix; 309 310 grafana = handleTest ./grafana {}; 310 311 grafana-agent = handleTest ./grafana-agent.nix {}; 311 312 graphite = handleTest ./graphite.nix {};
+28
nixos/tests/web-apps/gotosocial.nix
··· 1 + { lib, ... }: 2 + { 3 + name = "gotosocial"; 4 + meta.maintainers = with lib.maintainers; [ misuzu ]; 5 + 6 + nodes.machine = { pkgs, ... }: { 7 + environment.systemPackages = [ pkgs.jq ]; 8 + services.gotosocial = { 9 + enable = true; 10 + setupPostgresqlDB = true; 11 + settings = { 12 + host = "localhost:8081"; 13 + port = 8081; 14 + }; 15 + }; 16 + }; 17 + 18 + testScript = '' 19 + machine.wait_for_unit("gotosocial.service") 20 + machine.wait_for_unit("postgresql.service") 21 + machine.wait_for_open_port(8081) 22 + 23 + # check user registration via cli 24 + machine.succeed("curl -sS -f http://localhost:8081/nodeinfo/2.0 | jq '.usage.users.total' | grep -q '^0$'") 25 + machine.succeed("gotosocial-admin account create --username nickname --email email@example.com --password kurtz575VPeBgjVm") 26 + machine.succeed("curl -sS -f http://localhost:8081/nodeinfo/2.0 | jq '.usage.users.total' | grep -q '^1$'") 27 + ''; 28 + }
+64
pkgs/servers/gotosocial/default.nix
··· 1 + { stdenv 2 + , lib 3 + , fetchurl 4 + , fetchFromGitHub 5 + , buildGoModule 6 + , nixosTests 7 + }: 8 + let 9 + owner = "superseriousbusiness"; 10 + repo = "gotosocial"; 11 + 12 + version = "0.9.0"; 13 + source-hash = "sha256-UZRIQTdVESCYv2KW7HUS2c4bS5qnB7wdwiYAgEJ60fU="; 14 + web-assets-hash = "sha256-OvgAr3obsK1JndLKmnjNY06dEbQKyP4xG/viBjCivvs="; 15 + 16 + web-assets = fetchurl { 17 + url = "https://github.com/${owner}/${repo}/releases/download/v${version}/${repo}_${version}_web-assets.tar.gz"; 18 + hash = web-assets-hash; 19 + }; 20 + in 21 + buildGoModule rec { 22 + inherit version; 23 + pname = repo; 24 + 25 + src = fetchFromGitHub { 26 + inherit owner repo; 27 + rev = "refs/tags/v${version}"; 28 + hash = source-hash; 29 + }; 30 + 31 + vendorHash = null; 32 + 33 + ldflags = [ 34 + "-s" 35 + "-w" 36 + "-X main.Version=${version}" 37 + ]; 38 + 39 + postInstall = '' 40 + tar xf ${web-assets} 41 + mkdir -p $out/share/gotosocial 42 + mv web $out/share/gotosocial/ 43 + ''; 44 + 45 + # tests are working only on x86_64-linux 46 + doCheck = stdenv.isLinux && stdenv.isx86_64; 47 + 48 + passthru.tests.gotosocial = nixosTests.gotosocial; 49 + 50 + meta = with lib; { 51 + homepage = "https://gotosocial.org"; 52 + changelog = "https://github.com/superseriousbusiness/gotosocial/releases/tag/v${version}"; 53 + description = "Fast, fun, ActivityPub server, powered by Go"; 54 + longDescription = '' 55 + ActivityPub social network server, written in Golang. 56 + You can keep in touch with your friends, post, read, and 57 + share images and articles. All without being tracked or 58 + advertised to! A light-weight alternative to Mastodon 59 + and Pleroma, with support for clients! 60 + ''; 61 + maintainers = with maintainers; [ misuzu ]; 62 + license = licenses.agpl3Only; 63 + }; 64 + }
+2
pkgs/top-level/all-packages.nix
··· 25735 25735 25736 25736 mastodon = callPackage ../servers/mastodon { }; 25737 25737 25738 + gotosocial = callPackage ../servers/gotosocial { }; 25739 + 25738 25740 materialize = callPackage ../servers/sql/materialize { 25739 25741 inherit (buildPackages.darwin) bootstrap_cmds; 25740 25742 inherit (darwin.apple_sdk.frameworks) DiskArbitration Foundation;