I now host my own videos (with PeerTube)

Today I've launched a separate server that contains my own PeerTube instance: videos.knazarov.com. All videos that I produce will be mirrored there, because I care about giving people an alternative to centralized platforms.

If you're curious how this is set up, here's a link to the configuration repo. The most interesting part that's not mentioned in the official wiki article on NixOS is the security. The way the article does this will keep the world-readable plain-text passwords in the configuration on the filesystem. My approach is to use SOPS and use a principle of minimal access permissions, and as such I've figured out how to store the passwords encrypted and expose them to only the required users.

For example, take the postgres init script. In this init script, you are setting up a peertube user. This is how the authors did it:


  postgresql = {
    enable = true;
    enableTCPIP = true;
    authentication = ''
      hostnossl peertube_local peertube_test 127.0.0.1/32 md5
    '';
    initialScript = pkgs.writeText "postgresql_init.sql" ''
      CREATE ROLE peertube_test LOGIN PASSWORD 'test123';
      CREATE DATABASE peertube_local TEMPLATE template0 ENCODING UTF8;
      GRANT ALL PRIVILEGES ON DATABASE peertube_local TO peertube_test;
      \connect peertube_local
      CREATE EXTENSION IF NOT EXISTS pg_trgm;
      CREATE EXTENSION IF NOT EXISTS unaccent;
    '';
  };

Notice that the password is in plain text here. This would put the password to /nix/store/ which is world-readable. Since the postgres recipe doesn't have a separate configuration parameter for users/passwords, I've stuffed the whole initialScript into SOPS secret, like this:


  services.postgresql = {
    enable = true;
    enableTCPIP = true;
    authentication = ''
      hostnossl peertube_local peertube_test 127.0.0.1/32 md5
    '';
    initialScript = config.sops.secrets.postgresql_init.path;
  };

  sops.secrets = {
    postgresql_init = {
      mode = "0440";
      group = config.users.groups.postgres.name;
    };
  };

And then put the whole init script into the SOPS-managed secret file.

Another nice thing that I did is plugging LetsEncrypt SSL certificate generation right into this config. The wiki doesn't bother with doing this, but you can actually combine:


  services.peertube = {
    enable = true;
    localDomain = "videos.knazarov.com";
    configureNginx = true;
    ...
  };
  services.nginx = {
    enable = true;
    virtualHosts = {
      "videos.knazarov.com" = {
        enableACME = true;
        forceSSL = true;
        locations."/" = { proxyPass = "http://127.0.0.1:9000"; };
      };
    };
    ...
  };

Initially I thought that specifying virtualHosts with enableACME would conflict with the autogenerated configuration that services.peertube is creating, but it didn't!

With this config, I can now reproduce this server again from scratch in one single command.

What's left to do is to set up fail2ban to get a bit more security and also configure backups.