Skip to content

Commit

Permalink
nixos/piped: split into 3 modules
Browse files Browse the repository at this point in the history
  • Loading branch information
Atemu committed Jul 11, 2024
1 parent 2787681 commit 98dd923
Show file tree
Hide file tree
Showing 5 changed files with 412 additions and 368 deletions.
4 changes: 3 additions & 1 deletion nixos/modules/module-list.nix
Original file line number Diff line number Diff line change
Expand Up @@ -1427,7 +1427,9 @@
./services/web-apps/phylactery.nix
./services/web-apps/photoprism.nix
./services/web-apps/pict-rs.nix
./services/web-apps/piped.nix
./services/web-apps/piped-backend.nix
./services/web-apps/piped-frontend.nix
./services/web-apps/piped-proxy.nix
./services/web-apps/plantuml-server.nix
./services/web-apps/plausible.nix
./services/web-apps/powerdns-admin.nix
Expand Down
207 changes: 207 additions & 0 deletions nixos/modules/services/web-apps/piped-backend.nix
Original file line number Diff line number Diff line change
@@ -0,0 +1,207 @@
{
lib,
config,
pkgs,
...
}:
let
this = config.services.piped.backend;
https =
domain: if lib.hasSuffix ".localhost" domain then "http://${domain}" else "https://${domain}";
in
{
options.services.piped.backend = {
enable = lib.mkEnableOption "Piped Backend";

package = lib.mkPackageOption pkgs "piped-backend" { };

port = lib.mkOption {
type = lib.types.port;
example = 8000;
default = 28769;
description = ''
The port Piped Backend should listen on.
To allow access from outside,
you can use either {option}`services.piped.backend.nginx`
or add `config.services.piped.backend.port` to {option}`networking.firewall.allowedTCPPorts`.
'';
};

settings = lib.mkOption {
# Not actually used for file generation but for setting constraints on the values
inherit (pkgs.formats.javaProperties { }) type;
description = ''
The settings Piped Backend should use.
See [config.properties](https://github.com/TeamPiped/Piped-Backend/blob/master/config.properties) for a list of all possible options.
'';
};

externalUrl = lib.mkOption {
type = lib.types.str;
example = "https://pipedapi.example.com";
default = https this.nginx.domain;
defaultText = "The {option}`nginx.domain`";
description = ''
The external URL of Piped Backend.
'';
};

nginx = {
enable = lib.mkEnableOption "nginx as a reverse proxy for Piped Backend";

domain = lib.mkOption {
type = lib.types.str;
default = "pipedapi.localhost";
description = ''
The domain Piped Backend is reachable on.
'';
};

pubsubExtraConfig = lib.mkOption {
type = lib.types.str;
default = "";
example = "allow all;";
description = ''
Nginx extra config for the `/webhooks/pubsub` route.
'';
};
};

database = {
createLocally =
lib.mkEnableOption "create a local database with PostgreSQL"
// lib.mkOption { default = true; };
host = lib.mkOption {
type = lib.types.str;
default = "127.0.0.1";
description = ''
The database host Piped should use.
'';
};

port = lib.mkOption {
type = lib.types.port;
default = config.services.postgresql.settings.port;
defaultText = lib.literalExpression "config.services.postgresql.settings.port";
description = ''
The database port Piped should use.
Defaults to the the default postgresql port.
'';
};

database = lib.mkOption {
type = lib.types.str;
default = "piped-backend";
description = ''
The database Piped should use.
'';
};

username = lib.mkOption {
type = lib.types.str;
default = "piped-backend";
description = ''
The database username Piped should use.
'';
};

passwordFile = lib.mkOption {
type = lib.types.path;
example = "/run/keys/db_password";
default = throw "You must specify a `passwordFile`.";
description = ''
Path to file containing the database password.
'';
};
};
};

config = lib.mkIf this.enable {
services.piped.backend = {
settings = {
PORT = toString this.port;
API_URL = this.externalUrl;
};
};

services.postgresql = lib.mkIf this.database.createLocally {
enable = true;
enableTCPIP = true; # Java can't talk postgres via UNIX sockets...
ensureDatabases = [ "piped-backend" ];
ensureUsers = [
{
name = "piped-backend";
ensureDBOwnership = true;
inherit (this.database) passwordFile;
}
];
};

systemd.services.piped-backend =
let
databaseServices = lib.mkIf this.database.createLocally [ "postgresql.service" ];
in
{
after = databaseServices;
bindsTo = databaseServices;
wantedBy = [ "multi-user.target" ];
serviceConfig = {
User = "piped-backend";
Group = "piped-backend";
DynamicUser = true;
RuntimeDirectory = "piped-backend";
WorkingDirectory = "%t/piped-backend"; # %t is the RuntimeDirectory root
LoadCredential = [ "databasePassword:${this.database.passwordFile}" ];
};
environment = this.settings;
# We can't pass the DB connection password directly and must therefore
# put it into a transient config file instead. The WokringDirectory is
# under the RuntimeDirectory which itself is in RAM and dies with the
# service. This isn't optimal as credentials cann still be evicted into
# swap but the service itself does not make any effort to secure the
# password either.
preStart = ''
cat << EOF > config.properties
hibernate.connection.url: jdbc:postgresql://${this.database.host}:${toString this.database.port}/${this.database.database}
hibernate.connection.driver_class: org.postgresql.Driver
hibernate.dialect: org.hibernate.dialect.PostgreSQLDialect
hibernate.connection.username: ${this.database.username}
hibernate.connection.password: $(cat $CREDENTIALS_DIRECTORY/databasePassword)
EOF
'';
script = ''
${this.package}/bin/piped-backend
'';
};

services.nginx = lib.mkIf this.nginx.enable {
enable = true;
appendHttpConfig = ''
proxy_cache_path /tmp/pipedapi_cache levels=1:2 keys_zone=pipedapi:4m max_size=2g inactive=60m use_temp_path=off;
'';
virtualHosts.${this.nginx.domain} = {
locations."/" = {
proxyPass = "http://127.0.0.1:${toString this.port}";
extraConfig = ''
proxy_cache pipedapi;
'';
};
locations."/webhooks/pubsub" = {
proxyPass = "http://127.0.0.1:${toString this.port}";
extraConfig = ''
proxy_cache pipedapi;
${this.nginx.pubsubExtraConfig}
'';
};
};
};
};

meta.maintainers = with lib.maintainers; [
defelo
atemu
];
}
63 changes: 63 additions & 0 deletions nixos/modules/services/web-apps/piped-frontend.nix
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
{
lib,
config,
pkgs,
...
}:
let
this = config.services.piped.frontend;
inherit (config.services.piped) backend;
https =
domain: if lib.hasSuffix ".localhost" domain then "http://${domain}" else "https://${domain}";
in
{
options.services.piped.frontend = {
enable = lib.mkEnableOption "Piped Frontend";

package = lib.mkPackageOption pkgs "piped-frontend" { };

domain = lib.mkOption {
type = lib.types.str;
default = "piped.localhost";
description = ''
The domain Piped Frontend is reachable on.
'';
};

externalUrl = lib.mkOption {
type = lib.types.str;
example = "https://piped.example.com";
default = https this.domain;
defaultText = "The {option}`domain`";
description = ''
The external URL of Piped Frontend.
'';
};
};

config = lib.mkIf this.enable {
services.piped.backend.settings = {
FRONTEND_URL = this.externalUrl;
};

services.nginx = {
enable = true;
virtualHosts.${this.domain} = {
locations."/" = {
root = pkgs.runCommand "piped-frontend-patched" { } ''
cp -r ${this.package} $out
chmod -R +w $out
# This is terrible but it's the upstream-intended method for this
${pkgs.gnused}/bin/sed -i 's|https://pipedapi.kavin.rocks|${backend.externalUrl}|g' $out/{opensearch.xml,assets/*}
'';
tryFiles = "$uri /index.html";
};
};
};
};

meta.maintainers = with lib.maintainers; [
defelo
atemu
];
}
Loading

0 comments on commit 98dd923

Please sign in to comment.