1
0
Fork 0
Fediversity/services/fediversity/pixelfed/default.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" ];
};
})
];
}