forked from fediversity/fediversity
		
	
		
			
				
	
	
		
			172 lines
		
	
	
	
		
			5.7 KiB
		
	
	
	
		
			Nix
		
	
	
	
	
	
			
		
		
	
	
			172 lines
		
	
	
	
		
			5.7 KiB
		
	
	
	
		
			Nix
		
	
	
	
	
	
{
 | 
						|
  config,
 | 
						|
  lib,
 | 
						|
  pkgs,
 | 
						|
  ...
 | 
						|
}:
 | 
						|
 | 
						|
let
 | 
						|
  inherit (lib)
 | 
						|
    mkIf
 | 
						|
    mkMerge
 | 
						|
    readFile
 | 
						|
    escapeShellArg
 | 
						|
    ;
 | 
						|
 | 
						|
in
 | 
						|
{
 | 
						|
  imports = [ ./options.nix ];
 | 
						|
 | 
						|
  config = mkMerge [
 | 
						|
    (mkIf
 | 
						|
      (
 | 
						|
        config.fediversity.garage.enable
 | 
						|
        && config.fediversity.pixelfed.s3AccessKeyFile != null
 | 
						|
        && config.fediversity.pixelfed.s3SecretKeyFile != null
 | 
						|
      )
 | 
						|
      {
 | 
						|
        fediversity.garage = {
 | 
						|
          ensureBuckets = {
 | 
						|
            pixelfed = {
 | 
						|
              website = true;
 | 
						|
              # TODO: these are too broad, after getting everything works narrow it down to the domain we actually want
 | 
						|
              corsRules = {
 | 
						|
                enable = true;
 | 
						|
                allowedHeaders = [ "*" ];
 | 
						|
                allowedMethods = [ "GET" ];
 | 
						|
                allowedOrigins = [ "*" ];
 | 
						|
              };
 | 
						|
            };
 | 
						|
          };
 | 
						|
 | 
						|
          ensureKeys = {
 | 
						|
            pixelfed = {
 | 
						|
              inherit (config.fediversity.pixelfed) s3AccessKeyFile s3SecretKeyFile;
 | 
						|
              ensureAccess = {
 | 
						|
                pixelfed = {
 | 
						|
                  read = true;
 | 
						|
                  write = true;
 | 
						|
                  owner = true;
 | 
						|
                };
 | 
						|
              };
 | 
						|
            };
 | 
						|
          };
 | 
						|
        };
 | 
						|
      }
 | 
						|
    )
 | 
						|
 | 
						|
    (mkIf config.fediversity.pixelfed.enable {
 | 
						|
      ## NOTE: Pixelfed as packaged in nixpkgs has a permission issue that prevents Nginx
 | 
						|
      ## from being able to serving the images. We fix it here, but this should be
 | 
						|
      ## upstreamed. See https://github.com/NixOS/nixpkgs/issues/235147
 | 
						|
      services.pixelfed.package = pkgs.pixelfed.overrideAttrs (old: {
 | 
						|
        patches = (old.patches or [ ]) ++ [ ./group-permissions.patch ];
 | 
						|
      });
 | 
						|
      users.users.nginx.extraGroups = [ "pixelfed" ];
 | 
						|
 | 
						|
      services.pixelfed = {
 | 
						|
        enable = true;
 | 
						|
        domain = config.fediversity.pixelfed.domain;
 | 
						|
 | 
						|
        ## FIXME: secrets management; we should have a service that writes the
 | 
						|
        ## `.env` file based on all the secrets that we need to put there.
 | 
						|
        secretFile = pkgs.writeText "secrets.env" ''
 | 
						|
          APP_KEY=adKK9EcY8Hcj3PLU7rzG9rJ6KKTOtYfA
 | 
						|
          AWS_ACCESS_KEY_ID=${readFile config.fediversity.pixelfed.s3AccessKeyFile}
 | 
						|
          AWS_SECRET_ACCESS_KEY=${readFile config.fediversity.pixelfed.s3SecretKeyFile}
 | 
						|
        '';
 | 
						|
 | 
						|
        ## Taeer feels like this way of configuring Nginx is odd; there should
 | 
						|
        ## instead be a `services.pixefed.nginx.enable` option and the actual Nginx
 | 
						|
        ## configuration should be in `services.nginx`. See eg. `pretix`.
 | 
						|
        ##
 | 
						|
        ## TODO: If that indeed makes sense, upstream.
 | 
						|
        nginx = {
 | 
						|
          forceSSL = true;
 | 
						|
          enableACME = true;
 | 
						|
          # locations."/public/".proxyPass = "${config.fediversity.garage.web.urlForBucket "pixelfed"}/public/";
 | 
						|
        };
 | 
						|
      };
 | 
						|
 | 
						|
      services.pixelfed.settings = {
 | 
						|
        ## NOTE: This depends on the targets, eg. universities might want control
 | 
						|
        ## over who has an account. We probably want a universal
 | 
						|
        ## `fediversity.openRegistration` option.
 | 
						|
        OPEN_REGISTRATION = true;
 | 
						|
 | 
						|
        FILESYSTEM_CLOUD = "s3";
 | 
						|
        PF_ENABLE_CLOUD = true;
 | 
						|
        AWS_DEFAULT_REGION = "garage";
 | 
						|
        AWS_URL = config.fediversity.garage.web.urlForBucket "pixelfed";
 | 
						|
        AWS_BUCKET = "pixelfed";
 | 
						|
        AWS_ENDPOINT = config.fediversity.garage.api.url;
 | 
						|
        AWS_USE_PATH_STYLE_ENDPOINT = false;
 | 
						|
      };
 | 
						|
 | 
						|
      ## Only ever run `pixelfed-data-setup` after `ensure-garage` has done its job.
 | 
						|
      ## Otherwise, everything crashed dramatically.
 | 
						|
      systemd.services.pixelfed-data-setup = {
 | 
						|
        after = [ "ensure-garage.service" ];
 | 
						|
      };
 | 
						|
 | 
						|
      networking.firewall.allowedTCPPorts = [
 | 
						|
        80
 | 
						|
        443
 | 
						|
      ];
 | 
						|
 | 
						|
      systemd.services.inject-initial-pixelfed-user = {
 | 
						|
        ## Make this service start after pixelfed has started successfully
 | 
						|
        after = [ "phpfpm-pixelfed.service" ];
 | 
						|
        requires = [ "phpfpm-pixelfed.service" ];
 | 
						|
 | 
						|
        serviceConfig = {
 | 
						|
          Type = "simple";
 | 
						|
          Restart = "on-failure";
 | 
						|
          RestartSec = "10s";
 | 
						|
          ExecStart = pkgs.writeShellScript "inject-initial-pixelfed-user.sh" ''
 | 
						|
            #!/bin/sh
 | 
						|
            set -euC
 | 
						|
 | 
						|
            ## NOTE: The packaging for Pixelfed provides a 'pixelfed-manage'
 | 
						|
            ## command that is added to the environment but isn't easily
 | 
						|
            ## grabable otherwise, so we go the ugly route and extract it from
 | 
						|
            ## the Horizon service that runs 'pixelfed-manage horizon'.
 | 
						|
 | 
						|
            pixelfed-manage () {
 | 
						|
              local f=${escapeShellArg config.systemd.services.pixelfed-horizon.serviceConfig.ExecStart}
 | 
						|
              "''${f% horizon}" "$@"
 | 
						|
            }
 | 
						|
 | 
						|
            ## NOTE: The 'user:table' command prints headers:
 | 
						|
            ##
 | 
						|
            ##   +----+----------+------+------------+
 | 
						|
            ##   | ID | Username | Name | Registered |
 | 
						|
            ##   +----+----------+------+------------+
 | 
						|
            ##
 | 
						|
            ## so we check whether that is all we got to know if there are any
 | 
						|
            ## users yet.
 | 
						|
 | 
						|
            users_table=$(pixelfed-manage user:table)
 | 
						|
            if [ "$(echo "$users_table" | wc -l)" -ne 3 ]; then
 | 
						|
              printf 'There are already users; nothing to do:\n\n%s' "$users_table"
 | 
						|
              exit 0
 | 
						|
            fi
 | 
						|
 | 
						|
            ## No user so far; let's go!
 | 
						|
 | 
						|
            pixelfed-manage user:create \
 | 
						|
              --name=${escapeShellArg config.fediversity.temp.initialUser.displayName} \
 | 
						|
              --username=${escapeShellArg config.fediversity.temp.initialUser.username} \
 | 
						|
              --email=${escapeShellArg config.fediversity.temp.initialUser.email} \
 | 
						|
              --password="$(cat ${escapeShellArg config.fediversity.temp.initialUser.passwordFile})" \
 | 
						|
              --confirm_email=1
 | 
						|
          '';
 | 
						|
        };
 | 
						|
 | 
						|
        # Set the service to automatically start
 | 
						|
        wantedBy = [ "multi-user.target" ];
 | 
						|
      };
 | 
						|
 | 
						|
    })
 | 
						|
  ];
 | 
						|
}
 |