1
0
Fork 0
nix-config/modules/nixos/services/ente-auth/default.nix

268 lines
7.1 KiB
Nix

{
lib,
pkgs,
config,
namespace,
...
}:
with lib;
with lib.${namespace};
let
cfg = config.${namespace}.services.ente;
cfgWeb = cfg.web;
cfgApi = cfg.api;
defaultUser = "ente";
defaultGroup = "ente";
dataDir = "/var/lib/ente";
yamlFormat = pkgs.formats.yaml { };
enteApp =
cfgWeb.package.override {
extraBuildEnv = {
NEXT_PUBLIC_ENTE_ENDPOINT = "https://ente-api.monapona.dev";
NEXT_TELEMETRY_DISABLED = "1";
};
};
in
{
options.${namespace}.services.ente = {
nginx = {
enable = mkEnableOption "Enable nginx for this service."
// {
default = true;
};
};
web = {
enable = mkEnableOption "Ente-Auth-Web";
package = mkOption {
description = "The package of Ente-Auth to use.";
type = types.package;
default = pkgs.awesome-flake.ente-web-auth;
};
domain = mkOption {
description = "The domain to serve ente-auth on.";
type = types.nullOr types.str;
default = "ente.stahl.sh";
};
};
api = {
enable = mkEnableOption "Ente-API";
package = mkOption {
description = "The package of Ente-API to use.";
type = types.package;
default = pkgs.museum;
};
user = mkOption {
type = types.str;
default = defaultUser;
description = "User under which museum runs.";
};
group = mkOption {
type = types.str;
default = defaultGroup;
description = "Group under which museum runs.";
};
domain = mkOption {
description = "The domain to serve the API on.";
type = types.nullOr types.str;
default = "ente-api.stahl.sh";
};
enableLocalDB = mkEnableOption "the automatic creation of a local postgres database for museum.";
settings = mkOption {
description = ''
Museum yaml configuration. Refer to upstream [local.yaml](https://github.com/ente-io/ente/blob/main/server/configurations/local.yaml) for more information.
You can specify secret values in this configuration by setting `somevalue._secret = "/path/to/file"` instead of setting `somevalue` directly.
'';
default = { };
type = types.submodule {
freeformType = yamlFormat.type;
options = {
db = {
host = mkOption {
type = types.str;
default = "/run/postgresql";
description = "The database host";
};
port = mkOption {
type = types.port;
default = 5432;
description = "The database port";
};
name = mkOption {
type = types.str;
default = "ente";
description = "The database name";
};
user = mkOption {
type = types.str;
default = "ente";
description = "The database user";
};
};
};
};
};
};
};
config = mkMerge [
(mkIf cfgApi.enable {
services.postgresql = mkIf cfgApi.enableLocalDB {
enable = true;
ensureUsers = [
{
name = "ente";
ensureDBOwnership = true;
}
];
ensureDatabases = [ "ente" ];
};
${namespace}.services.ente.api.settings = {
log-file = mkDefault "";
db = mkIf cfgApi.enableLocalDB {
host = "/run/postgresql";
port = 5432;
name = "ente";
user = "ente";
};
};
systemd.services.ente = {
description = "Ente.io Museum API Server";
after = [ "network.target" ] ++ optional cfgApi.enableLocalDB "postgresql.service";
requires = optional cfgApi.enableLocalDB "postgresql.service";
wantedBy = [ "multi-user.target" ];
preStart = ''
# Setup paths
mkdir -p ${dataDir}/configurations
cp ${yamlFormat.generate "local.yaml" cfgApi.settings} ${dataDir}/configurations/local.yml
'';
serviceConfig = {
ExecStart = getExe cfgApi.package;
Type = "simple";
Restart = "on-failure";
AmbientCapablities = [ ];
CapabilityBoundingSet = [ ];
LockPersonality = true;
MemoryDenyWriteExecute = true;
NoNewPrivileges = true;
PrivateMounts = true;
PrivateTmp = true;
PrivateUsers = false;
ProcSubset = "pid";
ProtectClock = true;
ProtectControlGroups = true;
ProtectHome = true;
ProtectHostname = true;
ProtectKernelLogs = true;
ProtectKernelModules = true;
ProtectKernelTunables = true;
ProtectProc = "invisible";
ProtectSystem = "strict";
RestrictAddressFamilies = [
"AF_INET"
"AF_INET6"
"AF_NETLINK"
"AF_UNIX"
];
RestrictNamespaces = true;
RestrictRealtime = true;
RestrictSUIDSGID = true;
SystemCallArchitectures = "native";
SystemCallFilter = "@system-service";
UMask = "077";
BindReadOnlyPaths = [
"${cfgApi.package}/share/museum/migrations:${dataDir}/migrations"
"${cfgApi.package}/share/museum/mail-templates:${dataDir}/mail-templates"
];
User = cfgApi.user;
Group = cfgApi.group;
SyslogIdentifier = "ente";
StateDirectory = "ente";
WorkingDirectory = dataDir;
RuntimeDirectory = "ente";
};
# Environment MUST be called local, otherwise we cannot log to stdout
environment = {
ENVIRONMENT = "local";
GIN_MODE = "release";
};
};
users = {
users = mkIf (cfgApi.user == defaultUser) {
${defaultUser} = {
description = "ente.io museum service user";
inherit (cfgApi) group;
isSystemUser = true;
home = dataDir;
};
};
groups = mkIf (cfgApi.group == defaultGroup) { ${defaultGroup} = { }; };
};
services.nginx = mkIf cfg.nginx.enable {
enable = true;
upstreams.museum = {
servers."localhost:8080" = { };
extraConfig = ''
zone museum 64k;
keepalive 20;
'';
};
virtualHosts.${cfgApi.domain} = {
forceSSL = true;
useACMEHost = "stahl.sh";
locations."/".proxyPass = "http://museum";
extraConfig = ''
client_max_body_size 4M;
'';
};
};
})
(mkIf cfgWeb.enable {
networking.firewall.allowedTCPPorts = mkIf cfg.nginx.enable [
80
443
];
awesome-flake.services.acme.enable = mkIf cfg.nginx.enable true;
services.nginx = mkIf cfg.nginx.enable {
enable = true;
virtualHosts."${cfgWeb.domain}" = {
forceSSL = true;
useACMEHost = "stahl.sh";
locations."/".root = enteApp;
};
};
})
];
}