Merge pull request #287565 from RatCornu/pingvin-share

This commit is contained in:
Sandro 2024-08-22 11:59:03 +02:00 committed by GitHub
commit a45dc99ba3
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
11 changed files with 416 additions and 2 deletions

View File

@ -17165,11 +17165,11 @@
name = "Szymon Scholz";
};
ratcornu = {
email = "ratcornu@skaven.org";
email = "ratcornu+programmation@skaven.org";
github = "RatCornu";
githubId = 98173832;
name = "Balthazar Patiachvili";
matrix = "@ratcornu:skweel.skaven.org";
matrix = "@ratcornu:skaven.org";
keys = [ { fingerprint = "1B91 F087 3D06 1319 D3D0 7F91 FA47 BDA2 6048 9ADA"; } ];
};
ratsclub = {

View File

@ -61,6 +61,8 @@
- [wg-access-server](https://github.com/freifunkMUC/wg-access-server/), an all-in-one WireGuard VPN solution with a web ui for connecting devices. Available at [services.wg-access-server](#opt-services.wg-access-server.enable).
- [Pingvin Share](https://github.com/stonith404/pingvin-share), a self-hosted file sharing platform and an alternative for WeTransfer. Available as [services.pingvin-share](#opt-services.pingvin-share.enable).
- [Envision](https://gitlab.com/gabmus/envision), a UI for building, configuring and running Monado, the open source OpenXR runtime. Available as [programs.envision](#opt-programs.envision.enable).
- [Localsend](https://localsend.org/), an open source cross-platform alternative to AirDrop. Available as [programs.localsend](#opt-programs.localsend.enable).

View File

@ -1467,6 +1467,7 @@
./services/web-apps/phylactery.nix
./services/web-apps/photoprism.nix
./services/web-apps/pict-rs.nix
./services/web-apps/pingvin-share.nix
./services/web-apps/plantuml-server.nix
./services/web-apps/plausible.nix
./services/web-apps/powerdns-admin.nix

View File

@ -0,0 +1,43 @@
# Pingvin Share {#module-services-pingvin-share}
A self-hosted file sharing platform and an alternative for WeTransfer.
## Configuration {#module-services-pingvin-share-basic-usage}
By default, the module will execute Pingvin Share backend and frontend on the ports 8080 and 3000.
I will run two systemd services named `pingvin-share-backend` and `pingvin-share-frontend` in the specified data directory.
Here is a basic configuration:
```nix
{
services-pingvin-share = {
enable = true;
openFirewall = true;
backend.port = 9010;
frontend.port = 9011;
};
}
```
## Reverse proxy configuration {#module-services-pingvin-share-reverse-proxy-configuration}
The prefered method to run this service is behind a reverse proxy not to expose an open port. This, you can configure Nginx such like this:
```nix
{
services-pingvin-share = {
enable = true;
hostname = "pingvin-share.domain.tld";
https = true;
nginx.enable = true;
};
}
```
Furthermore, you can increase the maximal size of an uploaded file with the option [services.nginx.clientMaxBodySize](#opt-services.nginx.clientMaxBodySize).

View File

@ -0,0 +1,226 @@
{
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";
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;
};
}

View File

@ -771,6 +771,7 @@ in {
php84 = handleTest ./php { php = pkgs.php84; };
phylactery = handleTest ./web-apps/phylactery.nix {};
pict-rs = handleTest ./pict-rs.nix {};
pingvin-share = handleTest ./pingvin-share.nix {} ;
pinnwand = handleTest ./pinnwand.nix {};
plantuml-server = handleTest ./plantuml-server.nix {};
plasma-bigscreen = handleTest ./plasma-bigscreen.nix {};

View File

@ -0,0 +1,26 @@
import ./make-test-python.nix (
{ lib, ... }:
{
name = "pingvin-share";
meta.maintainers = with lib.maintainers; [ ratcornu ];
nodes.machine =
{ ... }:
{
services.pingvin-share = {
enable = true;
backend.port = 9010;
frontend.port = 9011;
};
};
testScript = ''
machine.wait_for_unit("pingvin-share-frontend.service")
machine.wait_for_open_port(9010)
machine.wait_for_open_port(9011)
machine.succeed("curl --fail http://127.0.0.1:9010/api/configs")
machine.succeed("curl --fail http://127.0.0.1:9011/")
'';
}
)

View File

@ -0,0 +1,50 @@
{
lib,
buildNpmPackage,
vips,
pkg-config,
nodePackages,
src,
version,
nixosTests,
}:
buildNpmPackage {
pname = "pingvin-share-backend";
inherit version;
src = "${src}/backend";
npmInstallFlags = [ "--build-from-source" ];
installPhase = ''
cp -r . $out
ln -s $out/node_modules/.bin $out/bin
'';
preBuild = ''
prisma generate
'';
buildInputs = [ vips ];
nativeBuildInputs = [
pkg-config
nodePackages.prisma
];
npmDepsHash = "sha256-btjvX+2krSc0/bJqeLcVTqHBVWqiTFipp3MidO9wApY=";
makeCacheWritable = true;
npmFlags = [ "--legacy-peer-deps" ];
passthru.tests = {
pingvin-share = nixosTests.pingvin-share;
};
meta = with lib; {
description = "Backend of pingvin-share, a self-hosted file sharing platform";
homepage = "https://github.com/stonith404/pingvin-share";
downloadPage = "https://github.com/stonith404/pingvin-share/releases";
changelog = "https://github.com/stonith404/pingvin-share/releases/tag/v${version}";
license = licenses.bsd2;
maintainers = with maintainers; [ ratcornu ];
};
}

View File

@ -0,0 +1,21 @@
{
callPackage,
fetchFromGitHub,
recurseIntoAttrs,
}:
let
version = "0.29.0";
src = fetchFromGitHub {
owner = "stonith404";
repo = "pingvin-share";
rev = "v${version}";
hash = "sha256-ETsIGb6IxGruApUP05cuMtTDNAE23CI1Q2MmjxX3aPo=";
};
in
recurseIntoAttrs {
backend = callPackage ./backend.nix { inherit src version; };
frontend = callPackage ./frontend.nix { inherit src version; };
}

View File

@ -0,0 +1,42 @@
{
lib,
buildNpmPackage,
vips,
pkg-config,
src,
version,
nixosTests,
}:
buildNpmPackage {
pname = "pingvin-share-frontend";
inherit version;
src = "${src}/frontend";
npmInstallFlags = [ "--build-from-source" ];
installPhase = ''
cp -r . $out
ln -s $out/node_modules/.bin $out/bin
'';
buildInputs = [ vips ];
nativeBuildInputs = [ pkg-config ];
npmDepsHash = "sha256-66CUVLbq2XdOQAr69DcvxTMvOgSR/RTKPaq80JG+8dg=";
makeCacheWritable = true;
npmFlags = [ "--legacy-peer-deps" ];
passthru.tests = {
pingvin-share = nixosTests.pingvin-share;
};
meta = with lib; {
description = "Frontend of pingvin-share, a self-hosted file sharing platform";
homepage = "https://github.com/stonith404/pingvin-share";
downloadPage = "https://github.com/stonith404/pingvin-share/releases";
changelog = "https://github.com/stonith404/pingvin-share/releases/tag/v${version}";
license = licenses.bsd2;
maintainers = with maintainers; [ ratcornu ];
};
}

View File

@ -23170,6 +23170,8 @@ with pkgs;
pico-sdk = callPackage ../development/libraries/pico-sdk { };
pingvin-share = callPackage ../servers/pingvin-share { };
pinocchio = callPackage ../development/libraries/pinocchio { };
pipelight = callPackage ../tools/misc/pipelight {