nixpkgs/nixos/modules/services/web-apps/pingvin-share.nix

227 lines
6.1 KiB
Nix

{
config,
pkgs,
lib,
...
}:
let
cfg = config.services.pingvin-share;
inherit (lib)
mkOption
mkEnableOption
mkIf
mkPackageOption
types
;
in
{
options = {
services.pingvin-share = {
enable = mkEnableOption "Pingvin Share, a self-hosted file sharing platform";
user = mkOption {
type = types.str;
default = "pingvin";
description = ''
User account under which Pingvin Share runs.
'';
};
group = mkOption {
type = types.str;
default = "pingvin";
description = ''
Group under which Pingvin Share runs.
'';
};
openFirewall = mkOption {
type = types.bool;
default = false;
description = ''
Whether to open the firewall for the port in {option}`services.pingvin-share.frontend.port`.
'';
};
dataDir = mkOption {
type = types.path;
default = "/var/lib/pingvin-share";
example = "/var/lib/pingvin";
description = ''
The path to the data directory in which Pingvin Share will store its data.
'';
};
hostname = mkOption {
type = types.str;
default = "localhost:${toString cfg.backend.port}";
defaultText = lib.literalExpression "localhost:\${options.services.pingvin-share.backend.port}";
example = "pingvin-share.domain.tdl";
description = ''
The domain name of your instance. If null, the redirections will be made to localhost.
'';
};
https = mkOption {
type = types.bool;
default = false;
example = true;
description = ''
Whether to enable HTTPS for the domain.
'';
};
backend = {
package = mkPackageOption pkgs [
"pingvin-share"
"backend"
] { };
port = mkOption {
type = types.port;
default = 8080;
example = 9000;
description = ''
The port that the backend service of Pingvin Share will listen to.
'';
};
};
frontend = {
package = mkPackageOption pkgs [
"pingvin-share"
"frontend"
] { };
port = mkOption {
type = types.port;
default = 3000;
example = 8000;
description = ''
The port that the frontend service of Pingvin Share will listen to.
'';
};
};
nginx = {
enable = mkEnableOption "a Nginx reverse proxy for Pingvin Share.";
};
};
};
config = mkIf cfg.enable {
users.groups = mkIf (cfg.group == "pingvin") { pingvin = { }; };
users.users = mkIf (cfg.user == "pingvin") {
pingvin = {
group = cfg.group;
description = "Pingvin Share daemon user";
isSystemUser = true;
};
};
networking.firewall.allowedTCPPorts = mkIf cfg.openFirewall [ cfg.frontend.port ];
systemd.services.pingvin-share-backend = {
description = "Backend service of Pingvin Share, a self-hosted file sharing platform.";
wantedBy = [
"multi-user.target"
"pingvin-share-frontend.service"
];
before = [ "pingvin-share-frontend.service" ];
after = [
"network.target"
"network-online.target"
];
wants = [ "network-online.target" ];
environment = {
PRISMA_SCHEMA_ENGINE_BINARY = "${pkgs.prisma-engines}/bin/schema-engine";
PRISMA_QUERY_ENGINE_BINARY = "${pkgs.prisma-engines}/bin/query-engine";
PRISMA_QUERY_ENGINE_LIBRARY = "${pkgs.prisma-engines}/lib/libquery_engine.node";
PRISMA_INTROSPECTION_ENGINE_BINARY = "${pkgs.prisma-engines}/bin/introspection-engine";
PRISMA_FMT_BINARY = "${pkgs.prisma-engines}/bin/prisma-fmt";
BACKEND_PORT = toString cfg.backend.port;
DATABASE_URL = "file:${cfg.dataDir}/pingvin-share.db?connection_limit=1";
DATA_DIRECTORY = cfg.dataDir;
};
path = with pkgs; [
cfg.backend.package
openssl
prisma-engines
];
serviceConfig = {
User = cfg.user;
Group = cfg.group;
Type = "simple";
Restart = "on-failure";
ExecStartPre = [
"${cfg.backend.package}/node_modules/.bin/prisma migrate deploy"
"${cfg.backend.package}/node_modules/.bin/prisma db seed"
];
ExecStart = "${cfg.backend.package}/node_modules/.bin/ts-node dist/src/main";
StateDirectory = mkIf (cfg.dataDir == "/var/lib/pingvin-share") "pingvin-share";
WorkingDirectory = cfg.backend.package;
};
};
systemd.services.pingvin-share-frontend = {
description = "Frontend service of Pingvin Share, a self-hosted file sharing platform.";
wantedBy = [ "multi-user.target" ];
wants = [
"network-online.target"
"pingvin-share-backend.service"
];
after = [
"network-online.target"
"pingvin-share-backend.service"
];
environment = {
PORT = toString cfg.frontend.port;
API_URL = "${if cfg.https then "https" else "http"}://${cfg.hostname}";
};
path = [ cfg.frontend.package ];
serviceConfig = {
User = cfg.user;
Group = cfg.group;
Type = "simple";
Restart = "on-failure";
ExecStart = "${cfg.frontend.package}/node_modules/.bin/next start";
StateDirectory = mkIf (cfg.dataDir == "/var/lib/pingvin-share") "pingvin-share";
WorkingDirectory = cfg.frontend.package;
};
};
services.nginx = mkIf cfg.nginx.enable {
enable = lib.mkDefault true;
virtualHosts."${cfg.hostname}" = {
enableACME = cfg.https;
forceSSL = cfg.https;
locations."/" = {
proxyPass = "http://localhost:${toString cfg.frontend.port}";
recommendedProxySettings = true;
};
locations."/api" = {
proxyPass = "http://localhost:${toString cfg.backend.port}";
recommendedProxySettings = true;
};
};
};
};
meta = {
maintainers = with lib.maintainers; [ ratcornu ];
doc = ./pingvin-share.md;
};
}