2

Self-hosting GoToSocial on NixOS

 1 year ago
source link: https://notes.abhinavsarkar.net/2022/gotosocial-on-nixos
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.
neoserver,ios ssh client

Abhinav's Notes 2022-11-20 2♥️ 3🔁

Self-hosting GoToSocial on NixOS

GoToSocial is an ActivityPub server. It is a lightweight alternative to Mastodon, and very suitable for self-hosting single user instances1. Though it does not have all of Mastodon’s features (it’s getting there), it is already quite useable.

I decided to self-host GoToSocial on my VPS, pointing to my own domain. So instead of having a fediverse address like @[email protected], I’d have an address @[email protected]2.

First, we package GoToSocial for NixOS:

{ pkgs }:

let
  pname = "gotosocial";
  version = "0.5.2";
in pkgs.stdenv.mkDerivation {
  inherit pname version;
  src = pkgs.fetchzip {
    url = "https://github.com/superseriousbusiness/${pname}/releases/download/v${version}/${pname}_${version}_linux_amd64.tar.gz";
    sha256 = "sha256-AfHXsQm0NHaqoyv7Jg6LHqzHmuahBiyAqHIBbY6rDJg=";
    stripRoot = false;
  };
  installPhase = ''
    mkdir -p "$out"/bin
    mv gotosocial $out/bin/
    mv web $out/
  '';
}

nix/packages/gotosocial.nix

Next, we write a minimal3NixOS module to run GoToSocial:

{ options, lib, config, pkgs, ... }:

let
  serverName = "soc.abnv.me";
  port = 9755;
  userName = "gotosocial";
  serviceName = userName;
  dataDir = "/var/lib/${userName}";
  pkg = import ./nix/packages/gotosocial.nix { inherit pkgs; };
  serviceConfig = config.services."${serverName}";
  options = { enable = lib.mkEnableOption "${serverName} service"; };
in {
  options.services.${serverName} = options;
  config = lib.mkIf serviceConfig.enable {
    users.users.${userName} = {
      isSystemUser = true;
      group = userName;
      createHome = true;
      home = dataDir;
    };
    users.groups.${userName} = { };

    systemd.tmpfiles.rules = [
      "d ${dataDir}/data 1770 ${userName} ${userName}"
      "d ${dataDir}/media 1770 ${userName} ${userName}"
    ];

    environment.etc."${serviceName}.yaml".text = ''
      host: "${serverName}"
      bind-address: "localhost"
      port: ${port}
      db-type: "sqlite"
      db-address: "${dataDir}/data/sqlite.db"
      web-template-base-dir: "${pkg}/web/template/"
      web-asset-base-dir: "${pkg}/web/assets/"
      accounts-registration-open: false
      storage-local-base-path: "${dataDir}/media"
    '';

    systemd.services.${serviceName} = {
      enable = true;
      description = "${serviceName} service";
      restartIfChanged = true;
      restartTriggers =
        [ config.environment.etc."${serviceName}.yaml".source pkg ];
      wantedBy = [ "multi-user.target" ];
      serviceConfig = {
        User = userName;
        Group = userName;
        WorkingDirectory = dataDir;
        ExecStart = ''
          ${pkg}/bin/gotosocial \
            --config-path /etc/${serviceName}.yaml server start
          '';
      };
    };

    services.nginx.virtualHosts.${serverName} = {
      forceSSL = true;
      enableACME = true;
      locations."/" = {
        proxyPass = "http://127.0.0.1:${port}";
        extraConfig = ''
          proxy_set_header Upgrade $http_upgrade;
          proxy_set_header Connection $connection_upgrade;
        '';
      };
      extraConfig = ''
        client_max_body_size 40M;
      '';
    };
  };
}

First, we set up a user and a group for GoToSocial, and the directories for data and uploaded media. Then, we create the config file. We are using SQLite as the database here4. Next, we set up a Systemd service to run the GoToSocial binary with the created config file. Finally, we set up an Nginx virtual host to proxy requests to the GoToSocial process.

When we import and enable this module in our NixOS configuration, we have a self-hosted GoToSocial instance running. I have mine at soc.abnv.me, and you can follow me at @[email protected].

That’s it for now. Happy #twittermigration.

Like, repost, or reply to this note on Fediverse.

  1. GoToSocial provides only the backend server. You’ll need a frontend as well. Pinafore on web, or Tusky on Android work well. 

  2. It is also possible to have an address like @[email protected] with some extra configuration

  3. There are couple of ways we can improve this module:

    • By adding sandboxing for the GoToSocial process.
    • By adding automatic restarts on failures.
    • By adding a separate route in Nginx for better caching of public assets.

  4. GoToSocial also supports PostgreSQL

Powered by Precis abhinavsarkar.net


About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK