Compare commits
10 commits
e57ee8ebe9
...
2a03d86df5
Author | SHA1 | Date | |
---|---|---|---|
2a03d86df5 | |||
76f688b1e6 | |||
994a8e983e | |||
1729b90a2e | |||
61def8ccb0 | |||
c5ad01eac7 | |||
a2c58be308 | |||
6ef001f2a8 | |||
e42f4c212b | |||
ac7393b9e6 |
17
build.sh
Executable file
17
build.sh
Executable file
|
@ -0,0 +1,17 @@
|
|||
#!/usr/bin/env bash
|
||||
set -euo pipefail
|
||||
|
||||
BASE_DIR=$( cd -- "$( dirname -- "${BASH_SOURCE[0]}" )" &> /dev/null && pwd )
|
||||
cd "${BASE_DIR}"
|
||||
|
||||
rm -rf result
|
||||
mkdir result
|
||||
|
||||
echo "Building Frontend"
|
||||
nix build -v .#piped-frontend -o result/piped-frontend "$@"
|
||||
|
||||
echo "Building Backend"
|
||||
nix build -v .#piped-backend -o result/piped-backend "$@"
|
||||
|
||||
echo "Building Proxy"
|
||||
nix build -v .#piped-proxy -o result/piped-proxy "$@"
|
12
flake.lock
12
flake.lock
|
@ -18,11 +18,11 @@
|
|||
},
|
||||
"nixpkgs": {
|
||||
"locked": {
|
||||
"lastModified": 1693985761,
|
||||
"narHash": "sha256-K5b+7j7Tt3+AqbWkcw+wMeqOAWyCD1MH26FPZyWXpdo=",
|
||||
"lastModified": 1694422566,
|
||||
"narHash": "sha256-lHJ+A9esOz9vln/3CJG23FV6Wd2OoOFbDeEs4cMGMqc=",
|
||||
"owner": "NixOS",
|
||||
"repo": "nixpkgs",
|
||||
"rev": "0bffda19b8af722f8069d09d8b6a24594c80b352",
|
||||
"rev": "3a2786eea085f040a66ecde1bc3ddc7099f6dbeb",
|
||||
"type": "github"
|
||||
},
|
||||
"original": {
|
||||
|
@ -59,11 +59,11 @@
|
|||
"systems": "systems"
|
||||
},
|
||||
"locked": {
|
||||
"lastModified": 1692799911,
|
||||
"narHash": "sha256-3eihraek4qL744EvQXsK1Ha6C3CR7nnT8X2qWap4RNk=",
|
||||
"lastModified": 1694529238,
|
||||
"narHash": "sha256-zsNZZGTGnMOf9YpHKJqMSsa0dXbfmxeoJ7xHlrt+xmY=",
|
||||
"owner": "numtide",
|
||||
"repo": "flake-utils",
|
||||
"rev": "f9e7cf818399d17d347f847525c5a5a8032e4e44",
|
||||
"rev": "ff7b65b44d01cf9ba6a71320833626af21126384",
|
||||
"type": "github"
|
||||
},
|
||||
"original": {
|
||||
|
|
|
@ -20,22 +20,27 @@
|
|||
nixosModules.piped = import ./module/default.nix;
|
||||
nixosModules.default = self.nixosModules.piped;
|
||||
|
||||
overlays.piped = final: prev: {
|
||||
overlays.piped = final: _prev: rec {
|
||||
piped-frontend = final.callPackage ./packages/frontend {};
|
||||
piped-backend = final.callPackage ./packages/backend {
|
||||
jre = final.openjdk19_headless;
|
||||
jdk = final.openjdk19;
|
||||
};
|
||||
piped-proxy = final.callPackage ./packages/proxy {};
|
||||
piped-backend-deps = final.callPackage ./packages/backend/deps.nix {
|
||||
jdk = final.openjdk19;
|
||||
};
|
||||
};
|
||||
overlays.default = self.overlays.piped;
|
||||
}
|
||||
// utils.lib.eachSystem (utils.lib.defaultSystems) (system: let
|
||||
pkgs = import nixpkgs {
|
||||
inherit system;
|
||||
overlays = [self.overlay];
|
||||
overlays = [self.overlays.default];
|
||||
};
|
||||
in {
|
||||
formatter = pkgs.alejandra;
|
||||
|
||||
packages = {
|
||||
inherit (pkgs) piped-frontend;
|
||||
inherit (pkgs) piped-backend;
|
||||
|
|
14
meta.json
14
meta.json
|
@ -1,15 +1,15 @@
|
|||
{
|
||||
"frontend": {
|
||||
"rev": "caa3e83ab83c93d117fe89649b7834d46ce9d53d",
|
||||
"sha256": "sha256-nsLrSJlQBJ//qubPN1kHDlLcK7iDgJh5nMcNybFygeY="
|
||||
"rev": "42792d8ec4a24e9a85af5320a71a3a09e0ee941c",
|
||||
"sha256": "sha256-/iyHvUgV1doH0adB1jcXWj6zi30k8pmCa0RrAmHmmo8="
|
||||
},
|
||||
"backend": {
|
||||
"rev": "a8e6907305a2f2f29d88e6cd07a2d392ece922af",
|
||||
"sha256": "sha256-QJPyz//CtJB5e7egrvemYh/hBjlN58QRpVb8KAJtSZ4=",
|
||||
"deps-sha256": "sha256-CS6gu7U8loktSh5xLq98vnBFWHuuv9sLYmgAZtrdP4Y="
|
||||
"rev": "af6325b53791ed4f82632ad0c8736c71f0736362",
|
||||
"sha256": "sha256-VBl5FgHeYO4xrNNP/Yipf210rMJpgZwQFJMsLuEkuwQ=",
|
||||
"deps-sha256": "sha256-hvrA+IdNFw60QGdf8OdNl+fOz0/EJORp0TSJhg+huSA="
|
||||
},
|
||||
"proxy": {
|
||||
"rev": "e642b968a8d73e8af281fa9a70a6798393670ac0",
|
||||
"sha256": "sha256-LzCsUIjOl5D96tVW9K9zng/xiYCMthpFWtV5qX5WrEo="
|
||||
"rev": "884df6a08e4eacf9494be085f225770307d2c9d2",
|
||||
"sha256": "sha256-OkA6JVLPK6pog3cByCCAdfBOF5UOrtV4GoeLKGaYOWo="
|
||||
}
|
||||
}
|
||||
|
|
|
@ -4,58 +4,76 @@
|
|||
pkgs,
|
||||
...
|
||||
}: let
|
||||
inherit (lib.modules) mkIf;
|
||||
inherit (lib.modules) mkIf mkDefault;
|
||||
inherit (lib.trivial) boolToString;
|
||||
inherit (lib.attrsets) mapAttrsToList optionalAttrs;
|
||||
inherit (lib.strings) optionalString concatStringsSep;
|
||||
inherit (pkgs) writeText writeShellScript;
|
||||
inherit (pkgs) writeText;
|
||||
|
||||
cfg = config.services.piped;
|
||||
backendConfig = cfg.backend;
|
||||
nginxConfig = backendConfig.nginx;
|
||||
databaseConfig = backendConfig.database;
|
||||
|
||||
proxyConfig = cfg.proxy;
|
||||
frontendConfig = cfg.frontend;
|
||||
|
||||
backendSettings = backendConfig.settings;
|
||||
|
||||
sedEscapeSlashes = "sed 's#/#\\\/#'";
|
||||
sedEscapeSingleQuotes = "sed \"s#'#\\\'#\"";
|
||||
|
||||
backendConfig =
|
||||
backendConfigAttrs =
|
||||
{
|
||||
PORT = cfg.internalBackendPort;
|
||||
HTTP_WORKERS = cfg.httpWorkers;
|
||||
PROXY_PART = "https://${cfg.proxyDomain}";
|
||||
API_URL = "https://${cfg.backendDomain}";
|
||||
FRONTEND_URL = "https://${cfg.frontendDomain}";
|
||||
DISABLE_REGISTRATION = cfg.disableRegistrations;
|
||||
COMPROMISED_PASSWORD_CHECK = cfg.enableCompromisedPasswordCheck;
|
||||
FEED_RETENTION = cfg.feedRetentionDays;
|
||||
SUBSCRIPTIONS_EXPIRY = cfg.subscriptionRetentionDays;
|
||||
SPONSORBLOCK_SERVERS = concatStringsSep "," cfg.sponsorblockServers;
|
||||
DISABLE_RYD = cfg.disableRYD;
|
||||
DISABLE_LBRY = cfg.disableLBRYStreams;
|
||||
RYD_PROXY_URL = cfg.rydAPIURL;
|
||||
SENTRY_DSN = cfg.sentryDSN;
|
||||
"hibernate.connection.url" = "jdbc:postgresql://${cfg.postgresDBHost}:${toString cfg.postgresDBPort}/${cfg.postgresDBName}";
|
||||
"hibernate.connection.driver_class" = "org.postgresql.Driver";
|
||||
"hibernate.dialect" = "org.hibernate.dialect.PostgreSQLDialect";
|
||||
"hibernate.connection.username" = "${cfg.postgresDBUsername}";
|
||||
"hibernate.connection.password" =
|
||||
if cfg.postgresDBPasswordFile == null
|
||||
then cfg.postgresDBPassword
|
||||
else "POSTGRES_PASSWORD_PLACEHOLDER";
|
||||
PORT = backendConfig.internalPort;
|
||||
PROXY_PART = "https://${proxyConfig.domain}";
|
||||
API_URL = "https://${backendConfig.domain}";
|
||||
FRONTEND_URL = "https://${frontendConfig.domain}";
|
||||
|
||||
DISABLE_REGISTRATION = backendSettings.disableRegistrations;
|
||||
|
||||
FEED_RETENTION = backendSettings.feedRetentionDays;
|
||||
SUBSCRIPTIONS_EXPIRY = backendSettings.subscriptionRetentionDays;
|
||||
HTTP_WORKERS = backendSettings.httpWorkers;
|
||||
|
||||
SPONSORBLOCK_SERVERS = concatStringsSep "," backendSettings.sponsorblockServers;
|
||||
DISABLE_LBRY = backendSettings.disableLBRYStreams;
|
||||
COMPROMISED_PASSWORD_CHECK = backendSettings.enableCompromisedPasswordCheck;
|
||||
|
||||
DISABLE_RYD = backendConfig.ryd.disable;
|
||||
RYD_PROXY_URL = backendConfig.ryd.apiURL;
|
||||
|
||||
SENTRY_DSN = backendSettings.sentryDSN;
|
||||
|
||||
"hibernate.connection.url" = let
|
||||
inherit (databaseConfig) host port name databaseOptions;
|
||||
in "jdbc:postgresql://${host}:${toString port}/${name}${databaseOptions}";
|
||||
"hibernate.connection.driver_class" = databaseConfig.driverClass;
|
||||
"hibernate.dialect" = databaseConfig.dialect;
|
||||
"hibernate.connection.username" = "${databaseConfig.username}";
|
||||
}
|
||||
// (optionalAttrs cfg.enableCaptcha {
|
||||
CAPTCHA_API_URL = cfg.captchaAPIURL;
|
||||
// (optionalAttrs databaseConfig.usePassword {
|
||||
"hibernate.connection.password" =
|
||||
if databaseConfig.passwordFile == null
|
||||
then databaseConfig.password
|
||||
else "DATABASE_PASSWORD_PLACEHOLDER";
|
||||
})
|
||||
// (optionalAttrs backendConfig.captcha.enable {
|
||||
CAPTCHA_API_URL = backendConfig.captcha.apiURL;
|
||||
# This is substituted in the PreStart of piped-backend.service
|
||||
CAPTCHA_API_KEY =
|
||||
if cfg.captchaAPIKeyFile != ""
|
||||
if backendConfig.captcha.apiKeyFile != null
|
||||
then "CAPTCHA_API_KEY_FILE_PLACEHOLDER"
|
||||
else cfg.captchaAPIKey;
|
||||
else backendSettings.apiKey;
|
||||
})
|
||||
// (optionalAttrs cfg.enableFederation {
|
||||
MATRIX_SERVER = cfg.matrixServerAddr;
|
||||
// (optionalAttrs backendConfig.federation.enable {
|
||||
MATRIX_SERVER = backendConfig.federation.matrixServerAddr;
|
||||
# also substituted
|
||||
MATRIX_TOKEN =
|
||||
if cfg.matrixTokenFile != ""
|
||||
if backendConfig.federation.matrixTokenFile != ""
|
||||
then "MATRIX_TOKEN_FILE_PLACEHOLDER"
|
||||
else cfg.matrixToken;
|
||||
});
|
||||
else backendConfig.federation.matrixToken;
|
||||
})
|
||||
// backendSettings.extraSettings;
|
||||
|
||||
cfgValueToString = value:
|
||||
if builtins.isBool value
|
||||
|
@ -69,43 +87,64 @@
|
|||
|
||||
backendConfigFile =
|
||||
writeText "config.properties"
|
||||
(cfgToString backendConfig);
|
||||
(cfgToString backendConfigAttrs);
|
||||
in {
|
||||
config = mkIf (cfg.enable && !cfg.disableBackend) {
|
||||
systemd.tmpfiles.rules = ["d /run/piped-backend - piped piped"];
|
||||
config = mkIf (cfg.enable && backendConfig.enable) {
|
||||
systemd.tmpfiles.rules = [
|
||||
"d /run/piped-backend - piped piped"
|
||||
"f /run/piped-backend/config.properties 660 piped piped"
|
||||
];
|
||||
|
||||
# I ran into some weird issues with ExecStartPre in piped-backend for this script
|
||||
# so moved it to its own unit to run before
|
||||
# some sort of syscall issue with
|
||||
systemd.services.piped-backend-config-init = {
|
||||
serviceConfig.User = "piped";
|
||||
wantedBy = ["piped-backend.service"];
|
||||
script = let
|
||||
confFile = "/run/piped-backend/config.properties";
|
||||
in ''
|
||||
cat ${backendConfigFile} > ${confFile}
|
||||
|
||||
${optionalString
|
||||
(backendConfig.captcha.enable && backendConfig.captcha.apiKeyFile != null) ''
|
||||
VALUE="$(cat ${backendConfig.captcha.apiKeyFile} | ${sedEscapeSlashes})"
|
||||
sed -i "s/CAPTCHA_API_KEY_FILE_PLACEHOLDER/$VALUE/" ${confFile}
|
||||
''}
|
||||
|
||||
${optionalString
|
||||
(backendConfig.federation.enable && backendConfig.federation.matrixTokenFile != null) ''
|
||||
VALUE="$(cat ${backendConfig.federation.matrixTokenFile} | ${sedEscapeSlashes})"
|
||||
sed -i "s/MATRIX_TOKEN_FILE_PLACEHOLDER/$VALUE/" ${confFile}
|
||||
''}
|
||||
|
||||
${optionalString
|
||||
(databaseConfig.passwordFile != null) ''
|
||||
VALUE=$(cat ${databaseConfig.passwordFile} | ${sedEscapeSlashes})
|
||||
sed -i "s/DATABASE_PASSWORD_PLACEHOLDER/$VALUE/" ${confFile}
|
||||
''}
|
||||
|
||||
chown piped:piped ${confFile}
|
||||
'';
|
||||
};
|
||||
|
||||
systemd.services.piped-backend = {
|
||||
wantedBy = ["multi-user.target"];
|
||||
wants = [
|
||||
"piped-backend-config-init.service"
|
||||
];
|
||||
after = [
|
||||
"piped-backend-config-init.service"
|
||||
];
|
||||
|
||||
serviceConfig = {
|
||||
WorkingDirectory = "/run/piped-backend";
|
||||
ExecStartPre = let
|
||||
confFile = "/run/piped-backend/config.properties";
|
||||
in
|
||||
writeShellScript "piped-backend-init" ''
|
||||
[ -f "${confFile}" ] && rm ${confFile}
|
||||
cp ${backendConfigFile} ${confFile}
|
||||
chmod 660 ${confFile}
|
||||
|
||||
${optionalString (cfg.enableCaptcha && cfg.captchaAPIKeyFile != "") ''
|
||||
sed -i "s/CAPTCHA_API_KEY_FILE_PLACEHOLDER/$(cat ${cfg.captchaAPIKeyFile} | ${sedEscapeSlashes})/" ${confFile}
|
||||
''}
|
||||
|
||||
${optionalString
|
||||
(cfg.enableFederation && cfg.matrixTokenFile != "") ''
|
||||
sed -i "s/MATRIX_TOKEN_FILE_PLACEHOLDER/$(cat ${cfg.matrixTokenFile} | ${sedEscapeSlashes})/" ${confFile}
|
||||
''}
|
||||
|
||||
${optionalString
|
||||
(cfg.postgresDBPasswordFile != null) ''
|
||||
sed -i "s/POSTGRES_PASSWORD_PLACEHOLDER/$(cat ${cfg.postgresDBPasswordFile} | ${sedEscapeSlashes})/" ${confFile}
|
||||
''}
|
||||
'';
|
||||
|
||||
ExecStart = "${pkgs.piped-backend}/bin/piped-backend";
|
||||
ExecStart = "${backendConfig.package}/bin/piped-backend";
|
||||
|
||||
RestartSec = "5s";
|
||||
User = "piped";
|
||||
|
||||
WorkingDirectory = "/run/piped-backend";
|
||||
|
||||
CapabilityBoundingSet = "";
|
||||
PrivateDevices = true;
|
||||
PrivateUsers = true;
|
||||
|
@ -119,43 +158,30 @@ in {
|
|||
};
|
||||
};
|
||||
|
||||
# Set password for piped when running postgres as piped won't run with
|
||||
# passwordless authentication
|
||||
systemd.services.piped-password = mkIf (!cfg.disablePostgresDB) {
|
||||
serviceConfig = {
|
||||
Type = "oneshot";
|
||||
User = "postgres";
|
||||
};
|
||||
|
||||
wantedBy = ["piped-backend.service"];
|
||||
wants = ["postgresql.service"];
|
||||
after = ["postgresql.service"];
|
||||
|
||||
script = ''
|
||||
${config.services.postgresql.package}/bin/psql -c "ALTER USER ${cfg.postgresDBUsername} WITH PASSWORD '${
|
||||
if cfg.postgresDBPasswordFile != null
|
||||
then "$(cat ${cfg.postgresDBPasswordFile} | ${sedEscapeSingleQuotes})"
|
||||
else cfg.postgresDBPassword
|
||||
}';"
|
||||
'';
|
||||
};
|
||||
|
||||
services.postgresql = mkIf (!cfg.disablePostgresDB) {
|
||||
services.postgresql = mkIf (!databaseConfig.disablePostgresDB) {
|
||||
enable = true;
|
||||
ensureUsers = [
|
||||
{
|
||||
name = cfg.postgresDBUsername;
|
||||
ensurePermissions."DATABASE ${cfg.postgresDBName}" = "ALL PRIVILEGES";
|
||||
name = databaseConfig.username;
|
||||
ensurePermissions."DATABASE ${databaseConfig.name}" = "ALL PRIVILEGES";
|
||||
}
|
||||
];
|
||||
ensureDatabases = [cfg.postgresDBName];
|
||||
ensureDatabases = [
|
||||
databaseConfig.name
|
||||
];
|
||||
authentication = mkIf (databaseConfig.password == "") ''
|
||||
host ${databaseConfig.name} ${databaseConfig.username} samehost peer map=${databaseConfig.name}
|
||||
'';
|
||||
};
|
||||
|
||||
services.nginx.virtualHosts."${cfg.backendDomain}" = mkIf (!cfg.disableNginx) {
|
||||
forceSSL = cfg.nginxForceSSL;
|
||||
enableACME = cfg.nginxEnableACME;
|
||||
locations."/" = {
|
||||
proxyPass = "http://127.0.0.1:${toString cfg.internalBackendPort}";
|
||||
services.nginx = mkIf (!nginxConfig.disableNginx) {
|
||||
enable = true;
|
||||
virtualHosts."${backendConfig.domain}" = {
|
||||
forceSSL = mkDefault nginxConfig.forceSSL;
|
||||
enableACME = mkDefault nginxConfig.enableACME;
|
||||
locations."/" = {
|
||||
proxyPass = "http://127.0.0.1:${toString backendConfig.internalPort}";
|
||||
};
|
||||
};
|
||||
};
|
||||
};
|
||||
|
|
|
@ -1,274 +1,313 @@
|
|||
{
|
||||
config,
|
||||
lib,
|
||||
pkgs,
|
||||
...
|
||||
}: let
|
||||
inherit (lib) types;
|
||||
inherit (lib.modules) mkIf;
|
||||
inherit (lib.options) mkOption mkEnableOption;
|
||||
inherit (lib.options) mkOption mkEnableOption mkPackageOption;
|
||||
|
||||
cfg = config.services.piped;
|
||||
in {
|
||||
options.services.piped = {
|
||||
enable = mkEnableOption "piped";
|
||||
|
||||
frontendDomain = mkOption {
|
||||
type = types.str;
|
||||
description = "Domain where the frontend will be displayed";
|
||||
frontend = {
|
||||
# Enable implies turning on nginx for frontend as it is static files
|
||||
enable = mkOption {
|
||||
type = types.bool;
|
||||
default = cfg.enable;
|
||||
};
|
||||
package = mkPackageOption pkgs "piped-frontend" {};
|
||||
domain = mkOption {
|
||||
type = types.str;
|
||||
description = "Domain where the frontend will be displayed";
|
||||
};
|
||||
|
||||
nginx = {
|
||||
forceSSL = mkOption {
|
||||
type = types.bool;
|
||||
default = true;
|
||||
};
|
||||
|
||||
enableACME = mkOption {
|
||||
type = types.bool;
|
||||
default = true;
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
backendDomain = mkOption {
|
||||
type = types.nullOr types.str;
|
||||
description = "Domain where the backend will be hosted. Set to null for project's default backend";
|
||||
backend = {
|
||||
enable = mkOption {
|
||||
type = types.bool;
|
||||
default = cfg.enable;
|
||||
};
|
||||
package = mkPackageOption pkgs "piped-backend" {};
|
||||
domain = mkOption {
|
||||
type = types.str;
|
||||
description = "Domain used for the backend server";
|
||||
};
|
||||
|
||||
internalPort = mkOption {
|
||||
type = types.number;
|
||||
default = 3001;
|
||||
};
|
||||
|
||||
nginx = {
|
||||
disableNginx = mkOption {
|
||||
type = types.bool;
|
||||
default = false;
|
||||
description = "Turn off nginx for proxying backend, use backend.internalPort instead";
|
||||
};
|
||||
|
||||
forceSSL = mkOption {
|
||||
type = types.bool;
|
||||
default = true;
|
||||
};
|
||||
|
||||
enableACME = mkOption {
|
||||
type = types.bool;
|
||||
default = true;
|
||||
};
|
||||
};
|
||||
|
||||
database = {
|
||||
disablePostgresDB = mkOption {
|
||||
type = types.bool;
|
||||
default = false;
|
||||
description = "Manually configure a database instead";
|
||||
};
|
||||
|
||||
host = mkOption {
|
||||
type = types.str;
|
||||
default = "127.0.0.1";
|
||||
description = "Database host";
|
||||
};
|
||||
|
||||
port = mkOption {
|
||||
type = types.number;
|
||||
default = 5432;
|
||||
description = "Database port";
|
||||
};
|
||||
|
||||
name = mkOption {
|
||||
type = types.str;
|
||||
default = "piped";
|
||||
description = "Database name";
|
||||
};
|
||||
|
||||
username = mkOption {
|
||||
type = types.str;
|
||||
default = "piped";
|
||||
description = "Database username";
|
||||
};
|
||||
|
||||
usePassword = mkOption {
|
||||
type = types.bool;
|
||||
default = true;
|
||||
description = "Should use database password? If false then use passwordless auth or configure cert-based auth in databaseOptions";
|
||||
};
|
||||
|
||||
password = mkOption {
|
||||
type = types.str;
|
||||
default = "";
|
||||
description = "Database password (default is to allow passwordless auth for samehost for piped when empty)";
|
||||
};
|
||||
|
||||
passwordFile = mkOption {
|
||||
type = types.nullOr types.path;
|
||||
default = null;
|
||||
description = "Database password file, loaded at runtime";
|
||||
};
|
||||
|
||||
databaseOptions = mkOption {
|
||||
type = types.str;
|
||||
default = "";
|
||||
description = "Appended to end of ";
|
||||
};
|
||||
|
||||
driverClass = mkOption {
|
||||
type = types.str;
|
||||
default = "org.postgresql.Driver";
|
||||
description = "The driver class to be used for the database connection";
|
||||
};
|
||||
|
||||
dialect = mkOption {
|
||||
type = types.str;
|
||||
default = "org.hibernate.dialect.PostgreSQLDialect";
|
||||
example = "org.hibernate.dialect.CockroachDialect";
|
||||
description = "The dialect class to be used for the database connection";
|
||||
};
|
||||
};
|
||||
|
||||
captcha = {
|
||||
enable = mkEnableOption "piped-backend-captcha";
|
||||
|
||||
apiURL = mkOption {
|
||||
type = types.str;
|
||||
default = "";
|
||||
description = "API URL for Captcha (unknown protocol/standard, upstream project uses api.capmonster.cloud in example config)";
|
||||
};
|
||||
|
||||
apiKey = mkOption {
|
||||
type = types.str;
|
||||
default = "";
|
||||
description = "API Key for Captcha";
|
||||
};
|
||||
|
||||
apiKeyFile = mkOption {
|
||||
type = types.nullOr types.str;
|
||||
default = null;
|
||||
description = "API Key File for Captcha";
|
||||
};
|
||||
};
|
||||
|
||||
ryd = {
|
||||
disable = mkOption {
|
||||
type = types.bool;
|
||||
default = false;
|
||||
description = "Disables querying a Return YouTube Dislike server";
|
||||
};
|
||||
|
||||
apiURL = mkOption {
|
||||
type = types.str;
|
||||
default = "https://ryd-proxy.kavin.rocks";
|
||||
description = "API URL for a Return YouTube Dislike server";
|
||||
};
|
||||
};
|
||||
|
||||
federation = {
|
||||
# for Piped's Federation Shenanigan
|
||||
# https://github.com/TeamPiped/piped-federation#how-to-join
|
||||
enable = mkEnableOption "piped-backend-federation";
|
||||
|
||||
matrixServerAddr = mkOption {
|
||||
type = types.str;
|
||||
default = "";
|
||||
description = "Matrix server address for federation";
|
||||
};
|
||||
|
||||
matrixToken = mkOption {
|
||||
type = types.str;
|
||||
default = "";
|
||||
description = "Matrix access token";
|
||||
};
|
||||
|
||||
matrixTokenFile = mkOption {
|
||||
type = types.nullOr types.str;
|
||||
default = null;
|
||||
description = "Matrix access token file";
|
||||
};
|
||||
};
|
||||
|
||||
settings = {
|
||||
extraSettings = mkOption {
|
||||
type = types.attrs;
|
||||
default = {};
|
||||
description = "extra settings to pass to config.properties";
|
||||
};
|
||||
|
||||
disableRegistrations = mkOption {
|
||||
type = types.bool;
|
||||
default = false;
|
||||
description = "Disable user registrations";
|
||||
};
|
||||
|
||||
httpWorkers = mkOption {
|
||||
type = types.number;
|
||||
default = 2;
|
||||
description = "Number of workers for HTTP backend tasks";
|
||||
};
|
||||
|
||||
feedRetentionDays = mkOption {
|
||||
type = types.number;
|
||||
default = 30;
|
||||
description = "Days feed is stored for";
|
||||
};
|
||||
|
||||
subscriptionRetentionDays = mkOption {
|
||||
type = types.number;
|
||||
default = 30;
|
||||
description = "Days subscriptions are stored for unauthenticated users";
|
||||
};
|
||||
|
||||
sponsorblockServers = mkOption {
|
||||
type = types.listOf types.str;
|
||||
default = ["https://sponsor.ajay.app" "https://sponsorblock.kavin.rocks"];
|
||||
description = "Days subscriptions are stored for unauthenticated users";
|
||||
};
|
||||
|
||||
disableLBRYStreams = mkOption {
|
||||
type = types.bool;
|
||||
default = false;
|
||||
description = "Disable showing streams provided by LBRY";
|
||||
};
|
||||
|
||||
enableCompromisedPasswordCheck = mkOption {
|
||||
type = types.bool;
|
||||
default = true;
|
||||
description = "Use the haveibeenpwned API to check if user password have been compromised";
|
||||
};
|
||||
|
||||
sentryDSN = mkOption {
|
||||
type = types.nullOr types.str;
|
||||
default = null;
|
||||
description = "Public DSN for sentry error reporting";
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
proxyDomain = mkOption {
|
||||
type = types.str;
|
||||
description = "Domain used for the proxy server";
|
||||
};
|
||||
proxy = {
|
||||
enable = mkOption {
|
||||
type = types.bool;
|
||||
default = cfg.enable;
|
||||
};
|
||||
package = mkPackageOption pkgs "piped-proxy" {};
|
||||
domain = mkOption {
|
||||
type = types.str;
|
||||
description = "Domain used for the proxy server";
|
||||
};
|
||||
|
||||
disableNginx = mkOption {
|
||||
type = types.bool;
|
||||
default = false;
|
||||
description = "Turn off module's nginx servers, this means you will need to manually proxy everything";
|
||||
};
|
||||
internalPort = mkOption {
|
||||
type = types.number;
|
||||
default = 3002;
|
||||
};
|
||||
|
||||
nginxForceSSL = mkOption {
|
||||
type = types.bool;
|
||||
default = false;
|
||||
description = "Should SSL/TLS be force enabled by nginx";
|
||||
};
|
||||
nginx = {
|
||||
disableNginx = mkOption {
|
||||
type = types.bool;
|
||||
default = false;
|
||||
description = "Turn off nginx for proxying proxy, use proxy.internalPort instead, you will need the relevant extra nginx config in proxy.nix or similar for good performance";
|
||||
};
|
||||
|
||||
nginxEnableACME = mkOption {
|
||||
type = types.bool;
|
||||
default = false;
|
||||
description = "Should ACME be force enabled by nginx";
|
||||
};
|
||||
forceSSL = mkOption {
|
||||
type = types.bool;
|
||||
default = true;
|
||||
};
|
||||
|
||||
disableFrontend = mkOption {
|
||||
type = types.bool;
|
||||
default = false;
|
||||
description = "Don't host frontend";
|
||||
};
|
||||
enableACME = mkOption {
|
||||
type = types.bool;
|
||||
default = true;
|
||||
};
|
||||
};
|
||||
|
||||
disableBackend = mkOption {
|
||||
type = types.bool;
|
||||
default = false;
|
||||
description = "Don't host backend";
|
||||
};
|
||||
|
||||
disableProxy = mkOption {
|
||||
type = types.bool;
|
||||
default = false;
|
||||
description = "Don't host proxy";
|
||||
};
|
||||
|
||||
disablePostgresDB = mkOption {
|
||||
type = types.bool;
|
||||
default = false;
|
||||
description = "Manually configure postgres instead";
|
||||
};
|
||||
|
||||
postgresHost = mkOption {
|
||||
type = types.str;
|
||||
default = "127.0.0.1";
|
||||
description = "Host for postgres";
|
||||
};
|
||||
|
||||
postgresPort = mkOption {
|
||||
type = types.number;
|
||||
default = 5432;
|
||||
description = "Port for postgres";
|
||||
};
|
||||
|
||||
postgresDBName = mkOption {
|
||||
type = types.str;
|
||||
default = "piped";
|
||||
description = "Database name for piped";
|
||||
};
|
||||
|
||||
postgresDBUsername = mkOption {
|
||||
type = types.str;
|
||||
default = "piped";
|
||||
description = "Host postgres is on";
|
||||
};
|
||||
|
||||
postgresDBPassword = mkOption {
|
||||
type = types.str;
|
||||
default = "password";
|
||||
description = "Password to use for postgres";
|
||||
};
|
||||
|
||||
postgresDBPasswordFile = mkOption {
|
||||
type = types.nullOr types.str;
|
||||
default = null;
|
||||
description = "Password file to use for postgres, loaded at runtime";
|
||||
};
|
||||
|
||||
proxyIPv4Only = mkOption {
|
||||
type = types.bool;
|
||||
default = false;
|
||||
description = "Only use IPv4 when querying youtube's servers";
|
||||
};
|
||||
|
||||
proxyNginxExtraConfig = mkOption {
|
||||
type = types.lines;
|
||||
default = ''
|
||||
proxy_buffering on;
|
||||
proxy_buffers 1024 16k;
|
||||
proxy_set_header X-Forwarded-For "";
|
||||
proxy_set_header CF-Connecting-IP "";
|
||||
proxy_hide_header "alt-svc";
|
||||
sendfile on;
|
||||
sendfile_max_chunk 512k;
|
||||
tcp_nopush on;
|
||||
aio threads=default;
|
||||
aio_write on;
|
||||
directio 16m;
|
||||
proxy_hide_header Cache-Control;
|
||||
proxy_hide_header etag;
|
||||
proxy_http_version 1.1;
|
||||
proxy_set_header Connection keep-alive;
|
||||
proxy_max_temp_file_size 32m;
|
||||
access_log off;
|
||||
'';
|
||||
description = "Extra config for nginx on piped-proxy";
|
||||
};
|
||||
|
||||
httpWorkers = mkOption {
|
||||
type = types.number;
|
||||
default = 2;
|
||||
description = "Number of workers for HTTP backend tasks";
|
||||
};
|
||||
|
||||
feedRetentionDays = mkOption {
|
||||
type = types.number;
|
||||
default = 30;
|
||||
description = "Days feed is stored for";
|
||||
};
|
||||
|
||||
subscriptionRetentionDays = mkOption {
|
||||
type = types.number;
|
||||
default = 30;
|
||||
description = "Days subscriptions are stored for unauthenticated users";
|
||||
};
|
||||
|
||||
sponsorblockServers = mkOption {
|
||||
type = types.listOf types.str;
|
||||
default = ["https://sponsor.ajay.app" "https://sponsorblock.kavin.rocks"];
|
||||
description = "Days subscriptions are stored for unauthenticated users";
|
||||
};
|
||||
|
||||
disableRegistrations = mkOption {
|
||||
type = types.bool;
|
||||
default = true;
|
||||
description = "Disable user registrations";
|
||||
};
|
||||
|
||||
disableLBRYStreams = mkOption {
|
||||
type = types.bool;
|
||||
default = false;
|
||||
description = "Disable showing streams provided by LBRY Youtube Partnership";
|
||||
};
|
||||
|
||||
enableCompromisedPasswordCheck = mkOption {
|
||||
type = types.bool;
|
||||
default = true;
|
||||
description = "Use the haveibeenpwned API to check if user password have been compromised";
|
||||
};
|
||||
|
||||
enableCaptcha = mkOption {
|
||||
type = types.bool;
|
||||
default = true;
|
||||
description = "Enable captcha for registrations";
|
||||
};
|
||||
|
||||
sentryDSN = mkOption {
|
||||
type = types.str;
|
||||
default = "";
|
||||
description = "Public DSN for sentry error reporting";
|
||||
};
|
||||
|
||||
captchaAPIURL = mkOption {
|
||||
type = types.str;
|
||||
default = "";
|
||||
description = "API URL for Captcha";
|
||||
};
|
||||
|
||||
# TODO: Key & KeyFile should be only one or the other used
|
||||
|
||||
captchaAPIKey = mkOption {
|
||||
type = types.str;
|
||||
default = "";
|
||||
description = "API Key for Captcha";
|
||||
};
|
||||
|
||||
captchaAPIKeyFile = mkOption {
|
||||
type = types.str;
|
||||
default = "";
|
||||
description = "API Key File for Captcha";
|
||||
};
|
||||
|
||||
# TODO: run this, requires a go app and Tor server for proxy
|
||||
#enableRYDServer = mkOption {
|
||||
# type = types.bool;
|
||||
# default = true;
|
||||
# description = "Run a RYD Proxy Server to use";
|
||||
#};
|
||||
|
||||
disableRYD = mkOption {
|
||||
type = types.bool;
|
||||
#default = if cfg.enableRYDServer then false else true;
|
||||
default = false;
|
||||
description = "Disables querying a Return YouTube Dislike server";
|
||||
};
|
||||
|
||||
rydAPIURL = mkOption {
|
||||
type = types.str;
|
||||
#default = if cfg.enableRYDServer then cfg.rydProxyDomain else "https://ryd-proxy.kavin.rocks";
|
||||
default = "https://ryd-proxy.kavin.rocks";
|
||||
description = "API URL for a Return YouTube Dislike server";
|
||||
};
|
||||
|
||||
# for Piped's Federation Shenanigan
|
||||
# https://github.com/TeamPiped/piped-federation#how-to-join
|
||||
enableFederation = mkOption {
|
||||
type = types.bool;
|
||||
default = false;
|
||||
description = "Enable federation of something";
|
||||
};
|
||||
|
||||
matrixServerAddr = mkOption {
|
||||
type = types.str;
|
||||
default = "";
|
||||
description = "Matrix server address for federation";
|
||||
};
|
||||
|
||||
# TODO: make so only one of these options can be used
|
||||
matrixToken = mkOption {
|
||||
type = types.str;
|
||||
default = "";
|
||||
description = "Matrix access token";
|
||||
};
|
||||
|
||||
matrixTokenFile = mkOption {
|
||||
type = types.str;
|
||||
default = "";
|
||||
description = "Matrix access token file";
|
||||
};
|
||||
|
||||
internalBackendPort = mkOption {
|
||||
type = types.number;
|
||||
default = 3001;
|
||||
};
|
||||
|
||||
internalProxyPort = mkOption {
|
||||
type = types.number;
|
||||
default = 3002;
|
||||
proxyIPv4Only = mkOption {
|
||||
type = types.bool;
|
||||
default = false;
|
||||
description = "Only use IPv4 when querying youtube's servers";
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
config = mkIf (cfg.enable && (!cfg.disableBackend || !cfg.disableProxy)) {
|
||||
config = mkIf (cfg.enable && (cfg.backend.enable || cfg.proxy.enable)) {
|
||||
assertions = [
|
||||
{
|
||||
assertion = cfg.backend.captcha.enable && cfg.backend.captcha.apiKey != "" && cfg.backend.captcha.apiKeyFile != null -> cfg.certsDir != null;
|
||||
message = "you must use either of services.piped.backend.captcha.{apiKey,apiKeyFile}";
|
||||
}
|
||||
];
|
||||
|
||||
users.users."piped" = {
|
||||
isSystemUser = true;
|
||||
group = "piped";
|
||||
|
@ -280,6 +319,5 @@ in {
|
|||
./backend.nix
|
||||
./frontend.nix
|
||||
./proxy.nix
|
||||
./nginx.nix
|
||||
];
|
||||
}
|
||||
|
|
|
@ -1,29 +1,38 @@
|
|||
{
|
||||
config,
|
||||
lib,
|
||||
pkgs,
|
||||
...
|
||||
}: let
|
||||
inherit (lib.modules) mkIf;
|
||||
inherit (lib.modules) mkIf mkDefault;
|
||||
|
||||
cfg = config.services.piped;
|
||||
|
||||
frontendPackage =
|
||||
pkgs.piped-frontend.override {backendDomain = cfg.backendDomain;};
|
||||
backendConfig = cfg.backend;
|
||||
frontendConfig = cfg.frontend;
|
||||
nginxConfig = frontendConfig.nginx;
|
||||
|
||||
frontendPackage = frontendConfig.package.override {
|
||||
backendDomain = backendConfig.domain;
|
||||
};
|
||||
in {
|
||||
config = mkIf (cfg.enable && !cfg.disableFrontend && !cfg.disableNginx) {
|
||||
config = mkIf (cfg.enable && frontendConfig.enable) {
|
||||
# https://github.com/TeamPiped/Piped/blob/master/docker/nginx.conf
|
||||
services.nginx.virtualHosts."${cfg.frontendDomain}" = {
|
||||
forceSSL = cfg.nginxForceSSL;
|
||||
enableACME = cfg.nginxEnableACME;
|
||||
locations."/" = {
|
||||
root = "${frontendPackage}/share/piped-frontend";
|
||||
index = "index.html index.htm";
|
||||
services.nginx = {
|
||||
enable = true;
|
||||
|
||||
virtualHosts."${frontendConfig.domain}" = {
|
||||
forceSSL = mkDefault nginxConfig.forceSSL;
|
||||
enableACME = mkDefault nginxConfig.enableACME;
|
||||
|
||||
locations."/" = {
|
||||
root = "${frontendPackage}/share/piped-frontend";
|
||||
index = "index.html index.htm";
|
||||
};
|
||||
# I have no idea why try_files for Single Page Apps doesn't work here
|
||||
extraConfig = ''
|
||||
error_page 404 =200 /index.html;
|
||||
'';
|
||||
};
|
||||
# I have no idea why try_files for Single Page Apps doesn't work here
|
||||
extraConfig = ''
|
||||
error_page 404 =200 /index.html;
|
||||
'';
|
||||
};
|
||||
};
|
||||
}
|
||||
|
|
|
@ -1,11 +0,0 @@
|
|||
{
|
||||
config,
|
||||
lib,
|
||||
...
|
||||
}: let
|
||||
cfg = config.services.piped;
|
||||
in {
|
||||
config = lib.mkIf (cfg.enable && !cfg.disableNginx) {
|
||||
services.nginx.enable = true;
|
||||
};
|
||||
}
|
|
@ -1,19 +1,42 @@
|
|||
{
|
||||
config,
|
||||
lib,
|
||||
pkgs,
|
||||
...
|
||||
}:
|
||||
with lib; let
|
||||
}: let
|
||||
inherit (lib.modules) mkIf mkDefault;
|
||||
|
||||
cfg = config.services.piped;
|
||||
|
||||
proxyConfig = cfg.proxy;
|
||||
nginxConfig = proxyConfig.nginx;
|
||||
|
||||
defaultNginxExtraConfig = ''
|
||||
proxy_buffering on;
|
||||
proxy_buffers 1024 16k;
|
||||
proxy_set_header X-Forwarded-For "";
|
||||
proxy_set_header CF-Connecting-IP "";
|
||||
proxy_hide_header "alt-svc";
|
||||
sendfile on;
|
||||
sendfile_max_chunk 512k;
|
||||
tcp_nopush on;
|
||||
aio threads=default;
|
||||
aio_write on;
|
||||
directio 16m;
|
||||
proxy_hide_header Cache-Control;
|
||||
proxy_hide_header etag;
|
||||
proxy_http_version 1.1;
|
||||
proxy_set_header Connection keep-alive;
|
||||
proxy_max_temp_file_size 32m;
|
||||
access_log off;
|
||||
'';
|
||||
in {
|
||||
config = mkIf (cfg.enable && !cfg.disableProxy) {
|
||||
config = mkIf (cfg.enable && proxyConfig.enable) {
|
||||
systemd.services.piped-proxy = {
|
||||
wantedBy = ["multi-user.target"];
|
||||
environment.BIND = "0.0.0.0:${toString cfg.internalProxyPort}";
|
||||
environment.IPV4_ONLY = mkIf cfg.proxyIPv4Only "1";
|
||||
environment.BIND = "0.0.0.0:${toString proxyConfig.internalPort}";
|
||||
environment.IPV4_ONLY = mkIf proxyConfig.proxyIPv4Only "1";
|
||||
serviceConfig = {
|
||||
ExecStart = "${pkgs.piped-proxy}/bin/piped-proxy";
|
||||
ExecStart = "${proxyConfig.package}/bin/piped-proxy";
|
||||
|
||||
RestartSec = "5s";
|
||||
User = "piped";
|
||||
|
@ -31,24 +54,28 @@ in {
|
|||
};
|
||||
};
|
||||
|
||||
services.nginx.virtualHosts."${cfg.proxyDomain}" = lib.mkIf (!cfg.disableNginx) {
|
||||
forceSSL = cfg.nginxForceSSL;
|
||||
enableACME = cfg.nginxEnableACME;
|
||||
locations."/" = {
|
||||
proxyPass = "http://localhost:${toString cfg.internalProxyPort}";
|
||||
extraConfig =
|
||||
cfg.proxyNginxExtraConfig
|
||||
+ ''
|
||||
services.nginx = mkIf (!nginxConfig.disableNginx) {
|
||||
enable = true;
|
||||
|
||||
virtualHosts."${proxyConfig.domain}" = {
|
||||
forceSSL = mkDefault nginxConfig.forceSSL;
|
||||
enableACME = mkDefault nginxConfig.enableACME;
|
||||
|
||||
locations."/" = {
|
||||
proxyPass = "http://localhost:${toString proxyConfig.internalPort}";
|
||||
extraConfig = ''
|
||||
${defaultNginxExtraConfig}
|
||||
add_header Cache-Control "public, max-age=604800";
|
||||
'';
|
||||
};
|
||||
locations."~ (/videoplayback|/api/v4/|/api/manifest/)" = {
|
||||
proxyPass = "http://localhost:${toString cfg.internalProxyPort}";
|
||||
extraConfig =
|
||||
cfg.proxyNginxExtraConfig
|
||||
+ ''
|
||||
};
|
||||
|
||||
locations."~ (/videoplayback|/api/v4/|/api/manifest/)" = {
|
||||
proxyPass = "http://localhost:${toString proxyConfig.internalPort}";
|
||||
extraConfig = ''
|
||||
${defaultNginxExtraConfig}
|
||||
add_header Cache-Control private always;
|
||||
'';
|
||||
};
|
||||
};
|
||||
};
|
||||
};
|
||||
|
|
|
@ -8,11 +8,11 @@
|
|||
perl,
|
||||
writeText,
|
||||
callPackage,
|
||||
piped-backend-deps,
|
||||
}: let
|
||||
meta = builtins.fromJSON (builtins.readFile ../../meta.json);
|
||||
|
||||
deps =
|
||||
callPackage ./deps.nix {inherit stdenv fetchFromGitHub jdk gradle perl;};
|
||||
deps = piped-backend-deps;
|
||||
|
||||
gradleInit = writeText "init.gradle" ''
|
||||
logger.lifecycle 'Replacing Maven repositories with ${deps}...'
|
||||
|
|
File diff suppressed because it is too large
Load diff
File diff suppressed because it is too large
Load diff
|
@ -1,6 +1,9 @@
|
|||
{
|
||||
rustPlatform,
|
||||
fetchFromGitHub,
|
||||
nasm,
|
||||
withWebP ? true,
|
||||
withAVIF ? true,
|
||||
}: let
|
||||
meta = builtins.fromJSON (builtins.readFile ../../meta.json);
|
||||
rev = meta.proxy.rev;
|
||||
|
@ -15,6 +18,25 @@ in
|
|||
sha256 = "${meta.proxy.sha256}";
|
||||
};
|
||||
|
||||
buildNoDefaultFeatures = true;
|
||||
buildFeatures =
|
||||
[]
|
||||
++ (
|
||||
if withAVIF
|
||||
then ["avif"]
|
||||
else []
|
||||
)
|
||||
++ (
|
||||
if withWebP
|
||||
then ["webp"]
|
||||
else []
|
||||
);
|
||||
|
||||
nativeBuildInputs =
|
||||
if withAVIF
|
||||
then [nasm]
|
||||
else [];
|
||||
|
||||
cargoLock = {lockFile = "${src}/Cargo.lock";};
|
||||
doCheck = false;
|
||||
}
|
||||
|
|
52
readme.md
Normal file
52
readme.md
Normal file
|
@ -0,0 +1,52 @@
|
|||
# Piped-Flake
|
||||
This is a flake which allows you to run Piped on NixOS.
|
||||
|
||||
This should allow for more advanced and declarative configuration than the upstream docker containers. It also includes more documentation on config files.
|
||||
|
||||
## How to run
|
||||
|
||||
This should provide a working piped instance.
|
||||
|
||||
You can look at the options in module/default.nix for more information.
|
||||
|
||||
```nix
|
||||
nixpkgs.overlays = [ inputs.piped-flake.overlays.default ];
|
||||
imports = [ inputs.piped-flake.nixosModules.default ];
|
||||
|
||||
services.piped = let
|
||||
baseDomain = "example.org";
|
||||
in {
|
||||
enable = true;
|
||||
|
||||
frontend = {
|
||||
domain = "${baseDomain}";
|
||||
};
|
||||
|
||||
backend = {
|
||||
domain = "backend.${baseDomain}";
|
||||
};
|
||||
|
||||
proxy = {
|
||||
domain = "proxy.${baseDomain}";
|
||||
};
|
||||
}
|
||||
```
|
||||
|
||||
## Supported Systems
|
||||
|
||||
`x86_64-linux` and `aarch64-linux` are both supported
|
||||
|
||||
However if you are deploying to `aarch64-linux` from a non-arm64 host via `qemu-user`` or using aarch64 builders without `--max-jobs=0` then the build of piped-backend will fail.
|
||||
|
||||
https://github.com/NixOS/nixpkgs/issues/255780
|
||||
|
||||
This appears to be a problem with upstream gradle.
|
||||
|
||||
For now you will have to build on a `aarch64-linux` host or use one as builder with `--max-jobs=0` to not use local host to build.
|
||||
|
||||
You can use the below on a `aarch64-linux` host to build and copy the built backend to your computer.
|
||||
|
||||
```sh
|
||||
nix build .#piped-backend --system aarch64-linux
|
||||
nix-copy-closure --to root@host-ip --use-substitutes $(readlink result)
|
||||
```
|
|
@ -16,7 +16,7 @@ json_set() {
|
|||
# Frontend
|
||||
old_frontend_rev=$(json_get '.frontend.rev')
|
||||
new_frontend_rev=$(curl -L "https://api.github.com/repos/TeamPiped/Piped/commits" 2>/dev/null | jq ".[0].sha" -r)
|
||||
if [ "$new_frontend_rev" != "$old_frontend_rev" ] || [ "${FORCE_UPDATE-}" != "" ]; then
|
||||
if [ "$new_frontend_rev" != "$old_frontend_rev" ] || [ "${UPDATE-}" == "frontend" ]; then
|
||||
echo "Frontend is out of date. Updating..."
|
||||
json_set '.frontend.rev' "$new_frontend_rev"
|
||||
json_set '.frontend.sha256' ""
|
||||
|
@ -27,6 +27,7 @@ if [ "$new_frontend_rev" != "$old_frontend_rev" ] || [ "${FORCE_UPDATE-}" != ""
|
|||
pushd Piped
|
||||
git reset --hard "$new_frontend_rev"
|
||||
#yarn install --no-lockfile
|
||||
# yarn add unocss@0.56.4
|
||||
yarn install --mode update-lockfile
|
||||
nix run "github:NixOS/nixpkgs/nixos-unstable#yarn2nix" > "${BASE_DIR}/packages/frontend/yarn.nix"
|
||||
cp yarn.lock "${BASE_DIR}/packages/frontend/yarn.lock"
|
||||
|
@ -38,7 +39,7 @@ fi
|
|||
# Backend
|
||||
old_backend_rev=$(json_get '.backend.rev')
|
||||
new_backend_rev=$(curl -L "https://api.github.com/repos/TeamPiped/Piped-Backend/commits" 2>/dev/null | jq ".[0].sha" -r)
|
||||
if [ "$new_backend_rev" != "$old_backend_rev" ] || [ "${FORCE_UPDATE-}" != "" ]; then
|
||||
if [ "$new_backend_rev" != "$old_backend_rev" ] || [ "${FORCE_UPDATE-}" == "backend" ]; then
|
||||
echo "Backend is out of date. Updating..."
|
||||
json_set '.backend.rev' "$new_backend_rev"
|
||||
json_set '.backend.sha256' ""
|
||||
|
@ -48,7 +49,7 @@ fi
|
|||
# Proxy
|
||||
old_proxy_rev=$(json_get '.proxy.rev')
|
||||
new_proxy_rev=$(curl -L "https://api.github.com/repos/TeamPiped/piped-proxy/commits" 2>/dev/null | jq ".[0].sha" -r)
|
||||
if [ "$new_proxy_rev" != "$old_proxy_rev" ] || [ "${FORCE_UPDATE-}" != "" ]; then
|
||||
if [ "$new_proxy_rev" != "$old_proxy_rev" ] || [ "${FORCE_UPDATE-}" == "proxy" ]; then
|
||||
echo "Proxy is out of date. Updating..."
|
||||
json_set '.proxy.rev' "$new_proxy_rev"
|
||||
json_set '.proxy.sha256' ""
|
||||
|
|
Loading…
Reference in a new issue