Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We鈥檒l occasionally send you account related emails.

Already on GitHub? Sign in to your account

nixos/pingvin-share: init at 0.25.0 #287565

Open
wants to merge 5 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
4 changes: 2 additions & 2 deletions maintainers/maintainer-list.nix
Original file line number Diff line number Diff line change
Expand Up @@ -17191,11 +17191,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";
}];
Expand Down
2 changes: 2 additions & 0 deletions nixos/doc/manual/release-notes/rl-2411.section.md
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,8 @@

- [Quickwit](https://quickwit.io), sub-second search & analytics engine on cloud storage. Available as [services.quickwit](options.html#opt-services.quickwit).

- [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).

## Backward Incompatibilities {#sec-release-24.11-incompatibilities}

- `nginx` package no longer includes `gd` and `geoip` dependencies. For enabling it, override `nginx` package with the optionals `withImageFilter` and `withGeoIP`.
Expand Down
1 change: 1 addition & 0 deletions nixos/modules/module-list.nix
Original file line number Diff line number Diff line change
Expand Up @@ -1423,6 +1423,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
Expand Down
43 changes: 43 additions & 0 deletions nixos/modules/services/web-apps/pingvin-share.md
Original file line number Diff line number Diff line change
@@ -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).
199 changes: 199 additions & 0 deletions nixos/modules/services/web-apps/pingvin-share.nix
Original file line number Diff line number Diff line change
@@ -0,0 +1,199 @@
{ config, pkgs, lib, ... }:

let
cfg = config.services.pingvin-share;
inherit (lib) mkOption mkEnableOption mkIf mkPackageOptionMD 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 = mkPackageOptionMD 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 = mkPackageOptionMD 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" ];
wants = [ "network-online.target" ];
before = [ "pingvin-share-frontend.service" ];
after = [ "network.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;
};
}
1 change: 1 addition & 0 deletions nixos/tests/all-tests.nix
Original file line number Diff line number Diff line change
Expand Up @@ -732,6 +732,7 @@ in {
php83 = handleTest ./php { php = pkgs.php83; };
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 {};
Expand Down
21 changes: 21 additions & 0 deletions nixos/tests/pingvin-share.nix
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
import ./make-test-python.nix ({ lib, pkgs, ... }: {
name = "pingvin-share";
meta.maintainers = with lib.maintainers; [ ratcornu ];

nodes.machine = { pkgs, ... }: {
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/")
'';
})
46 changes: 46 additions & 0 deletions pkgs/servers/pingvin-share/backend.nix
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
{ lib
, buildNpmPackage
, vips
, pkg-config
, nodePackages
, src
, version
}:

let
prisma = nodePackages.prisma;
in

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 prisma ];


npmDepsHash = "sha256-eHHK30lZnF9As2NFXCHwoEKrfHI5vyo12OWyDDHdsYM=";
makeCacheWritable = true;
npmFlags = [ "--legacy-peer-deps" ];

meta = with lib; {
description = "The backend of pingvin-share, a self-hosted file sharing platform and an alternative for WeTransfer.";
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 ];
};
}
25 changes: 25 additions & 0 deletions pkgs/servers/pingvin-share/default.nix
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
{ callPackage
, fetchFromGitHub
, recurseIntoAttrs
, nixosTests
}:

let
version = "0.25.0";
src = fetchFromGitHub {
owner = "stonith404";
repo = "pingvin-share";
rev = "v${version}";
hash = "sha256-uwuW7n7pFCIV3/sDi6bYaJPWcK9Gc4xIZFidIN3Tq5E=";
};
in

recurseIntoAttrs {
backend = callPackage ./backend.nix { inherit src version; };

frontend = callPackage ./frontend.nix { inherit src version; };

passthru.tests = {
pingvin-share = nixosTests.pingvin-share;
};
}