Migrate Mastodon to NixOS
This commit is contained in:
		
					parent
					
						
							
								db63ad370d
							
						
					
				
			
			
				commit
				
					
						6b447c40aa
					
				
			
		
					 11 changed files with 256 additions and 78 deletions
				
			
		
							
								
								
									
										43
									
								
								config/hosts/mastodon/configuration.nix
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										43
									
								
								config/hosts/mastodon/configuration.nix
									
										
									
									
									
										Normal file
									
								
							| 
						 | 
				
			
			@ -0,0 +1,43 @@
 | 
			
		|||
{ ... }:
 | 
			
		||||
{
 | 
			
		||||
  boot.loader.grub = {
 | 
			
		||||
    enable = true;
 | 
			
		||||
    device = "/dev/vda";
 | 
			
		||||
  };
 | 
			
		||||
 | 
			
		||||
  networking = {
 | 
			
		||||
    hostName = "mastodon";
 | 
			
		||||
    firewall = {
 | 
			
		||||
      enable = true;
 | 
			
		||||
      allowedTCPPorts = [ 80 8443 ];
 | 
			
		||||
    };
 | 
			
		||||
  };
 | 
			
		||||
 | 
			
		||||
  fileSystems = {
 | 
			
		||||
    "/mnt/data" = {
 | 
			
		||||
      device = "/dev/disk/by-label/data";
 | 
			
		||||
      fsType = "ext4";
 | 
			
		||||
      autoResize = true;
 | 
			
		||||
    };
 | 
			
		||||
    "/var/lib/mastodon/public-system" = {
 | 
			
		||||
      depends = [ "/mnt/data" ];
 | 
			
		||||
      device = "/mnt/data/mastodon";
 | 
			
		||||
      fsType = "none";
 | 
			
		||||
      options = [ "bind" "X-mount.owner=mastodon" "X-mount.group=mastodon" ];
 | 
			
		||||
    };
 | 
			
		||||
    "/var/lib/postgresql" = {
 | 
			
		||||
      depends = [ "/mnt/data" ];
 | 
			
		||||
      device = "/mnt/data/postgresql";
 | 
			
		||||
      fsType = "none";
 | 
			
		||||
      options = [ "bind" "X-mount.owner=postgres" "X-mount.group=postgres" ];
 | 
			
		||||
    };
 | 
			
		||||
    "/var/lib/private/opensearch/data" = {
 | 
			
		||||
      depends = [ "/mnt/data" ];
 | 
			
		||||
      device = "/mnt/data/opensearch";
 | 
			
		||||
      fsType = "none";
 | 
			
		||||
      options = [ "bind" "X-mount.owner=opensearch" "X-mount.group=opensearch" ];
 | 
			
		||||
    };
 | 
			
		||||
  };
 | 
			
		||||
 | 
			
		||||
  system.stateVersion = "23.05";
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										9
									
								
								config/hosts/mastodon/default.nix
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										9
									
								
								config/hosts/mastodon/default.nix
									
										
									
									
									
										Normal file
									
								
							| 
						 | 
				
			
			@ -0,0 +1,9 @@
 | 
			
		|||
{ ... }:
 | 
			
		||||
{
 | 
			
		||||
  imports = [
 | 
			
		||||
    ./configuration.nix
 | 
			
		||||
    ./mastodon.nix
 | 
			
		||||
    ./opensearch.nix
 | 
			
		||||
    ./nginx.nix
 | 
			
		||||
  ];
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										51
									
								
								config/hosts/mastodon/mastodon.nix
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										51
									
								
								config/hosts/mastodon/mastodon.nix
									
										
									
									
									
										Normal file
									
								
							| 
						 | 
				
			
			@ -0,0 +1,51 @@
 | 
			
		|||
{ pkgs, ... }:
 | 
			
		||||
let
 | 
			
		||||
  mastodonNekoversePatches = pkgs.fetchgit {
 | 
			
		||||
    url = "https://github.com/yuri-qq/nekoverse-mastodon-patches.git";
 | 
			
		||||
    hash = "sha256-+HoE3rXiJUpAUYiXj4BaOL68cCG1tN8p+TI7vRxrA1Y=";
 | 
			
		||||
  };
 | 
			
		||||
  mastodonNekoverseOverlay = final: prev: {
 | 
			
		||||
    mastodon = (prev.mastodon.override rec {
 | 
			
		||||
      version = "4.1.9";
 | 
			
		||||
      srcOverride = final.applyPatches {
 | 
			
		||||
        src = final.fetchgit {
 | 
			
		||||
          url = "https://github.com/mastodon/mastodon.git";
 | 
			
		||||
          rev = "v${version}";
 | 
			
		||||
          sha256 = "sha256-xpE/mg2AeioW6NThUjLS+SBxGavG4w1xtp3BOMADfYo=";
 | 
			
		||||
        };
 | 
			
		||||
        patches = [
 | 
			
		||||
          "${mastodonNekoversePatches}/patches/001_increase_image_dimensions_limit.patch"
 | 
			
		||||
          "${mastodonNekoversePatches}/patches/002_disable_image_reprocessing.patch"
 | 
			
		||||
          "${mastodonNekoversePatches}/patches/003_make_toot_cute.patch"
 | 
			
		||||
          "${mastodonNekoversePatches}/patches/005_improve_custom_emoji_support.patch"
 | 
			
		||||
          "${mastodonNekoversePatches}/patches/006_increase_display_name_character_limit.patch"
 | 
			
		||||
          "${mastodonNekoversePatches}/patches/007_increase_toot_character_limit.patch"
 | 
			
		||||
        ];
 | 
			
		||||
      };
 | 
			
		||||
    });
 | 
			
		||||
  };
 | 
			
		||||
  pkgs-overlay = pkgs.extend mastodonNekoverseOverlay;
 | 
			
		||||
in
 | 
			
		||||
{
 | 
			
		||||
  services.mastodon = {
 | 
			
		||||
    enable = true;
 | 
			
		||||
    package = pkgs-overlay.mastodon;
 | 
			
		||||
    localDomain = "social.nekover.se";
 | 
			
		||||
    secretKeyBaseFile = "/secrets/mastodon-secret-key-base.secret";
 | 
			
		||||
    otpSecretFile = "/secrets/mastodon-otp-secret.secret";
 | 
			
		||||
    vapidPrivateKeyFile = "/secrets/mastodon-vapid-private-key.secret";
 | 
			
		||||
    smtp = {
 | 
			
		||||
      authenticate = true;
 | 
			
		||||
      host = "mail-1.grzb.de";
 | 
			
		||||
      port = 465;
 | 
			
		||||
      user = "social@nekover.se";
 | 
			
		||||
      passwordFile = "/secrets/mastodon-email-smtp-pass.secret";
 | 
			
		||||
      fromAddress = "Nekoverse <nyareply@nekover.se>";
 | 
			
		||||
    };
 | 
			
		||||
    extraConfig = {
 | 
			
		||||
      SMTP_TLS = "true";
 | 
			
		||||
      ES_PRESET = "single_node_cluster";
 | 
			
		||||
    };
 | 
			
		||||
    elasticsearch.host = "127.0.0.1";
 | 
			
		||||
  };
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										48
									
								
								config/hosts/mastodon/nginx.nix
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										48
									
								
								config/hosts/mastodon/nginx.nix
									
										
									
									
									
										Normal file
									
								
							| 
						 | 
				
			
			@ -0,0 +1,48 @@
 | 
			
		|||
{ config, ... }:
 | 
			
		||||
{
 | 
			
		||||
  services.nginx = {
 | 
			
		||||
    enable = true;
 | 
			
		||||
    group = "mastodon";
 | 
			
		||||
    virtualHosts."social.nekover.se" = {
 | 
			
		||||
      forceSSL = true;
 | 
			
		||||
      enableACME = true;
 | 
			
		||||
      listen = [
 | 
			
		||||
        {
 | 
			
		||||
          addr = "0.0.0.0";
 | 
			
		||||
          port = 80;
 | 
			
		||||
        }
 | 
			
		||||
        {
 | 
			
		||||
          addr = "0.0.0.0";
 | 
			
		||||
          port = 8443;
 | 
			
		||||
          ssl = true;
 | 
			
		||||
          extraParameters = [ "proxy_protocol" ];
 | 
			
		||||
        }
 | 
			
		||||
      ];
 | 
			
		||||
 | 
			
		||||
      root = "${config.services.mastodon.package}/public/";
 | 
			
		||||
 | 
			
		||||
      locations = {
 | 
			
		||||
        "/" = {
 | 
			
		||||
          tryFiles = "$uri @proxy";
 | 
			
		||||
        };
 | 
			
		||||
 | 
			
		||||
        "/system/".alias = "/var/lib/mastodon/public-system/";
 | 
			
		||||
 | 
			
		||||
        "^~ /api/v1/streaming" = {
 | 
			
		||||
          proxyPass = "http://unix:/run/mastodon-streaming/streaming.socket";
 | 
			
		||||
          proxyWebsockets = true;
 | 
			
		||||
        };
 | 
			
		||||
 | 
			
		||||
        "@proxy" = {
 | 
			
		||||
          proxyPass = "http://unix:/run/mastodon-web/web.socket";
 | 
			
		||||
          proxyWebsockets = true;
 | 
			
		||||
        };
 | 
			
		||||
      };
 | 
			
		||||
 | 
			
		||||
      extraConfig = ''
 | 
			
		||||
        set_real_ip_from 10.202.41.100;
 | 
			
		||||
        real_ip_header proxy_protocol;
 | 
			
		||||
      '';
 | 
			
		||||
    };
 | 
			
		||||
  };
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										5
									
								
								config/hosts/mastodon/opensearch.nix
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										5
									
								
								config/hosts/mastodon/opensearch.nix
									
										
									
									
									
										Normal file
									
								
							| 
						 | 
				
			
			@ -0,0 +1,5 @@
 | 
			
		|||
{ ... }: {
 | 
			
		||||
  services.opensearch = {
 | 
			
		||||
    enable = true;
 | 
			
		||||
  };
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										37
									
								
								config/hosts/mastodon/secrets.nix
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										37
									
								
								config/hosts/mastodon/secrets.nix
									
										
									
									
									
										Normal file
									
								
							| 
						 | 
				
			
			@ -0,0 +1,37 @@
 | 
			
		|||
{ ... }:
 | 
			
		||||
{
 | 
			
		||||
  deployment.keys = {
 | 
			
		||||
    "mastodon-secret-key-base.secret" = {
 | 
			
		||||
      keyCommand = [ "env" "GNUPGHOME=/home/yuri/.passinfra_gnupg" "PASSWORD_STORE_DIR=/home/yuri/pass/infra" "pass" "mastodon/secret-key-base" ];
 | 
			
		||||
      destDir = "/secrets";
 | 
			
		||||
      user = "mastodon";
 | 
			
		||||
      group = "mastodon";
 | 
			
		||||
      permissions = "0640";
 | 
			
		||||
      uploadAt = "pre-activation";
 | 
			
		||||
    };
 | 
			
		||||
    "mastodon-otp-secret.secret" = {
 | 
			
		||||
      keyCommand = [ "env" "GNUPGHOME=/home/yuri/.passinfra_gnupg" "PASSWORD_STORE_DIR=/home/yuri/pass/infra" "pass" "mastodon/otp-secret" ];
 | 
			
		||||
      destDir = "/secrets";
 | 
			
		||||
      user = "mastodon";
 | 
			
		||||
      group = "mastodon";
 | 
			
		||||
      permissions = "0640";
 | 
			
		||||
      uploadAt = "pre-activation";
 | 
			
		||||
    };
 | 
			
		||||
    "mastodon-vapid-private-key.secret" = {
 | 
			
		||||
      keyCommand = [ "env" "GNUPGHOME=/home/yuri/.passinfra_gnupg" "PASSWORD_STORE_DIR=/home/yuri/pass/infra" "pass" "mastodon/vapid-private-key" ];
 | 
			
		||||
      destDir = "/secrets";
 | 
			
		||||
      user = "mastodon";
 | 
			
		||||
      group = "mastodon";
 | 
			
		||||
      permissions = "0640";
 | 
			
		||||
      uploadAt = "pre-activation";
 | 
			
		||||
    };
 | 
			
		||||
    "mastodon-email-smtp-pass.secret" = {
 | 
			
		||||
      keyCommand = [ "env" "GNUPGHOME=/home/yuri/.passinfra_gnupg" "PASSWORD_STORE_DIR=/home/yuri/pass/infra" "pass" "mastodon/email-smtp-pass" ];
 | 
			
		||||
      destDir = "/secrets";
 | 
			
		||||
      user = "mastodon";
 | 
			
		||||
      group = "mastodon";
 | 
			
		||||
      permissions = "0640";
 | 
			
		||||
      uploadAt = "pre-activation";
 | 
			
		||||
    };
 | 
			
		||||
  };
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			@ -25,7 +25,7 @@
 | 
			
		|||
        nekover.se 127.0.0.1:8443;
 | 
			
		||||
        nextcloud.grzb.de 127.0.0.1:8443;
 | 
			
		||||
        nix-cache.nekover.se 10.202.41.121:8443;
 | 
			
		||||
        social.nekover.se 127.0.0.1:8443;
 | 
			
		||||
        social.nekover.se 10.202.41.104:8443;
 | 
			
		||||
      }
 | 
			
		||||
 | 
			
		||||
      server {
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -1,57 +1,68 @@
 | 
			
		|||
{ ... }:
 | 
			
		||||
{
 | 
			
		||||
  services.nginx.virtualHosts."jellyfin.grzb.de" = {
 | 
			
		||||
    listen = [{ 
 | 
			
		||||
      addr = "0.0.0.0";
 | 
			
		||||
      port = 80;
 | 
			
		||||
    }];
 | 
			
		||||
    locations."^~ /.well-known/acme-challenge/" = {
 | 
			
		||||
      proxyPass = "http://jellyfin.vs.grzb.de:80";
 | 
			
		||||
  services.nginx.virtualHosts = {
 | 
			
		||||
    "jellyfin.grzb.de" = {
 | 
			
		||||
      listen = [{ 
 | 
			
		||||
        addr = "0.0.0.0";
 | 
			
		||||
        port = 80;
 | 
			
		||||
      }];
 | 
			
		||||
      locations."^~ /.well-known/acme-challenge/" = {
 | 
			
		||||
        proxyPass = "http://jellyfin.vs.grzb.de:80";
 | 
			
		||||
      };
 | 
			
		||||
    };
 | 
			
		||||
  };
 | 
			
		||||
  services.nginx.virtualHosts."mail-1.grzb.de" = {
 | 
			
		||||
    listen = [{ 
 | 
			
		||||
      addr = "0.0.0.0";
 | 
			
		||||
      port = 80;
 | 
			
		||||
    }];
 | 
			
		||||
    locations."^~ /.well-known/acme-challenge/" = {
 | 
			
		||||
      proxyPass = "http://mail-1.vs.grzb.de:80";
 | 
			
		||||
    "mail-1.grzb.de" = {
 | 
			
		||||
      listen = [{ 
 | 
			
		||||
        addr = "0.0.0.0";
 | 
			
		||||
        port = 80;
 | 
			
		||||
      }];
 | 
			
		||||
      locations."^~ /.well-known/acme-challenge/" = {
 | 
			
		||||
        proxyPass = "http://mail-1.vs.grzb.de:80";
 | 
			
		||||
      };
 | 
			
		||||
    };
 | 
			
		||||
  };
 | 
			
		||||
  services.nginx.virtualHosts."matrix.nekover.se" = {
 | 
			
		||||
    listen = [{ 
 | 
			
		||||
      addr = "0.0.0.0";
 | 
			
		||||
      port = 80;
 | 
			
		||||
    }];
 | 
			
		||||
    locations."^~ /.well-known/acme-challenge/" = {
 | 
			
		||||
      proxyPass = "http://matrix.vs.grzb.de:80";
 | 
			
		||||
    "mastodon.nekover.se" = {
 | 
			
		||||
      listen = [{ 
 | 
			
		||||
        addr = "0.0.0.0";
 | 
			
		||||
        port = 80;
 | 
			
		||||
      }];
 | 
			
		||||
      locations."^~ /.well-known/acme-challenge/" = {
 | 
			
		||||
        proxyPass = "http://mastodon.vs.grzb.de:80";
 | 
			
		||||
      };
 | 
			
		||||
    };
 | 
			
		||||
  };
 | 
			
		||||
  services.nginx.virtualHosts."netbox.grzb.de" = {
 | 
			
		||||
    listen = [{ 
 | 
			
		||||
      addr = "0.0.0.0";
 | 
			
		||||
      port = 80;
 | 
			
		||||
    }];
 | 
			
		||||
    locations."^~ /.well-known/acme-challenge/" = {
 | 
			
		||||
      proxyPass = "http://netbox.vs.grzb.de:80";
 | 
			
		||||
    "matrix.nekover.se" = {
 | 
			
		||||
      listen = [{ 
 | 
			
		||||
        addr = "0.0.0.0";
 | 
			
		||||
        port = 80;
 | 
			
		||||
      }];
 | 
			
		||||
      locations."^~ /.well-known/acme-challenge/" = {
 | 
			
		||||
        proxyPass = "http://matrix.vs.grzb.de:80";
 | 
			
		||||
      };
 | 
			
		||||
    };
 | 
			
		||||
  };
 | 
			
		||||
  services.nginx.virtualHosts."grafana.grzb.de" = {
 | 
			
		||||
    listen = [{ 
 | 
			
		||||
      addr = "0.0.0.0";
 | 
			
		||||
      port = 80;
 | 
			
		||||
    }];
 | 
			
		||||
    locations."^~ /.well-known/acme-challenge/" = {
 | 
			
		||||
      proxyPass = "http://metrics.vs.grzb.de:80";
 | 
			
		||||
    "netbox.grzb.de" = {
 | 
			
		||||
      listen = [{ 
 | 
			
		||||
        addr = "0.0.0.0";
 | 
			
		||||
        port = 80;
 | 
			
		||||
      }];
 | 
			
		||||
      locations."^~ /.well-known/acme-challenge/" = {
 | 
			
		||||
        proxyPass = "http://netbox.vs.grzb.de:80";
 | 
			
		||||
      };
 | 
			
		||||
    };
 | 
			
		||||
  };
 | 
			
		||||
  services.nginx.virtualHosts."turn.nekover.se" = {
 | 
			
		||||
    listen = [{ 
 | 
			
		||||
      addr = "0.0.0.0";
 | 
			
		||||
      port = 80;
 | 
			
		||||
    }];
 | 
			
		||||
    locations."^~ /.well-known/acme-challenge/" = {
 | 
			
		||||
      proxyPass = "http://coturn.vs.grzb.de:80";
 | 
			
		||||
    "grafana.grzb.de" = {
 | 
			
		||||
      listen = [{ 
 | 
			
		||||
        addr = "0.0.0.0";
 | 
			
		||||
        port = 80;
 | 
			
		||||
      }];
 | 
			
		||||
      locations."^~ /.well-known/acme-challenge/" = {
 | 
			
		||||
        proxyPass = "http://metrics.vs.grzb.de:80";
 | 
			
		||||
      };
 | 
			
		||||
    };
 | 
			
		||||
    "turn.nekover.se" = {
 | 
			
		||||
      listen = [{ 
 | 
			
		||||
        addr = "0.0.0.0";
 | 
			
		||||
        port = 80;
 | 
			
		||||
      }];
 | 
			
		||||
      locations."^~ /.well-known/acme-challenge/" = {
 | 
			
		||||
        proxyPass = "http://coturn.vs.grzb.de:80";
 | 
			
		||||
      };
 | 
			
		||||
    };
 | 
			
		||||
  };
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -8,7 +8,6 @@
 | 
			
		|||
    ./git.grzb.de.nix
 | 
			
		||||
    ./mewtube.nekover.se.nix
 | 
			
		||||
    ./nekover.se.nix
 | 
			
		||||
    ./social.nekover.se.nix
 | 
			
		||||
  ];
 | 
			
		||||
 | 
			
		||||
  services.nginx.virtualHosts."_" = {
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -1,29 +0,0 @@
 | 
			
		|||
{ ... }:
 | 
			
		||||
{
 | 
			
		||||
  services.nginx.virtualHosts."social.nekover.se" = {
 | 
			
		||||
    forceSSL = true;
 | 
			
		||||
    enableACME = true;
 | 
			
		||||
    listen = [
 | 
			
		||||
      { 
 | 
			
		||||
        addr = "localhost";
 | 
			
		||||
        port = 1234;
 | 
			
		||||
      } # workaround for enableACME check
 | 
			
		||||
      {
 | 
			
		||||
        addr = "localhost";
 | 
			
		||||
        port = 8443;
 | 
			
		||||
        ssl = true;
 | 
			
		||||
        proxyProtocol = true;
 | 
			
		||||
      }
 | 
			
		||||
    ];
 | 
			
		||||
    locations."/" = {
 | 
			
		||||
      proxyPass = "http://mastodon.vs.grzb.de:80";
 | 
			
		||||
      proxyWebsockets = true;
 | 
			
		||||
    };
 | 
			
		||||
    extraConfig = ''
 | 
			
		||||
      client_max_body_size 80m;
 | 
			
		||||
 | 
			
		||||
      set_real_ip_from 127.0.0.1;
 | 
			
		||||
      real_ip_header proxy_protocol;
 | 
			
		||||
    '';
 | 
			
		||||
  };
 | 
			
		||||
}
 | 
			
		||||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue