Skip to content

Commit eb94a32

Browse files
committed
Add PeerTube (v3.0.1) pkg and service
1 parent 616453e commit eb94a32

File tree

8 files changed

+400
-0
lines changed

8 files changed

+400
-0
lines changed

nixos/modules/misc/ids.nix

+2
Original file line numberDiff line numberDiff line change
@@ -347,6 +347,7 @@ in
347347
#mailman = 316; # removed 2019-08-30
348348
zigbee2mqtt = 317;
349349
# shadow = 318; # unused
350+
peertube = 319;
350351

351352
# When adding a uid, make sure it doesn't match an existing gid. And don't use uids above 399!
352353

@@ -649,6 +650,7 @@ in
649650
#mailman = 316; # removed 2019-08-30
650651
zigbee2mqtt = 317;
651652
shadow = 318;
653+
peertube = 319;
652654

653655
# When adding a gid, make sure it doesn't match an existing
654656
# uid. Users and groups with the same name should have equal

nixos/modules/module-list.nix

+1
Original file line numberDiff line numberDiff line change
@@ -903,6 +903,7 @@
903903
./services/web-apps/moodle.nix
904904
./services/web-apps/nextcloud.nix
905905
./services/web-apps/nexus.nix
906+
./services/web-apps/peertube.nix
906907
./services/web-apps/plantuml-server.nix
907908
./services/web-apps/pgpkeyserver-lite.nix
908909
./services/web-apps/matomo.nix
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,186 @@
1+
{ lib, pkgs, config, ... }:
2+
3+
let
4+
name = "peertube";
5+
cfg = config.services.peertube;
6+
7+
uid = config.ids.uids.peertube;
8+
gid = config.ids.gids.peertube;
9+
in
10+
{
11+
options.services.peertube = {
12+
enable = lib.mkEnableOption "Enable Peertube’s service";
13+
14+
user = lib.mkOption {
15+
type = lib.types.str;
16+
default = name;
17+
description = "User account under which Peertube runs";
18+
};
19+
20+
group = lib.mkOption {
21+
type = lib.types.str;
22+
default = name;
23+
description = "Group under which Peertube runs";
24+
};
25+
26+
configFile = lib.mkOption {
27+
type = lib.types.path;
28+
description = ''
29+
The configuration file path for Peertube.
30+
'';
31+
};
32+
33+
database = {
34+
createLocally = lib.mkOption {
35+
description = "Configure local PostgreSQL database server for PeerTube.";
36+
type = lib.types.bool;
37+
default = true;
38+
};
39+
40+
name = lib.mkOption {
41+
type = lib.types.str;
42+
default = "peertube_prod";
43+
description = "Database name.";
44+
};
45+
46+
user = lib.mkOption {
47+
type = lib.types.str;
48+
default = "peertube";
49+
description = "Database user.";
50+
};
51+
};
52+
53+
smtp = {
54+
createLocally = lib.mkOption {
55+
description = "Configure local Postfix SMTP server for PeerTube.";
56+
type = lib.types.bool;
57+
default = true;
58+
};
59+
};
60+
61+
redis = {
62+
createLocally = lib.mkOption {
63+
description = "Configure local Redis server for PeerTube.";
64+
type = lib.types.bool;
65+
default = true;
66+
};
67+
};
68+
69+
runtimeDir = lib.mkOption {
70+
type = lib.types.path;
71+
default = "/var/lib/${name}";
72+
description = "The directory where Peertube stores its runtime data.";
73+
};
74+
75+
package = lib.mkOption {
76+
type = lib.types.package;
77+
default = pkgs.peertube;
78+
description = ''
79+
Peertube package to use.
80+
'';
81+
};
82+
};
83+
84+
config = lib.mkIf cfg.enable {
85+
users.users = lib.optionalAttrs (cfg.user == name) {
86+
"${name}" = {
87+
inherit uid;
88+
group = cfg.group;
89+
description = "Peertube user";
90+
home = cfg.runtimeDir;
91+
useDefaultShell = true;
92+
# todo: fix this. needed for postgres authentication
93+
password = "peertube";
94+
};
95+
};
96+
users.groups = lib.optionalAttrs (cfg.group == name) {
97+
"${name}" = {
98+
inherit gid;
99+
};
100+
};
101+
102+
services.postgresql = lib.mkIf cfg.database.createLocally {
103+
enable = true;
104+
ensureUsers = [ { name = cfg.database.user; }];
105+
# The database is created as a startup script of the peertube service.
106+
authentication = ''
107+
host ${cfg.database.name} ${cfg.database.user} 127.0.0.1/32 trust
108+
host ${cfg.database.name} ${cfg.database.user} 127.0.0.1/32 md5
109+
'';
110+
};
111+
112+
services.postfix = lib.mkIf cfg.smtp.createLocally {
113+
enable = true;
114+
};
115+
116+
services.redis = lib.mkIf cfg.redis.createLocally {
117+
enable = true;
118+
};
119+
120+
# Make sure the runtimeDir exists with the desired permissions.
121+
systemd.tmpfiles.rules = [
122+
"d \"${cfg.runtimeDir}\" - ${cfg.user} ${cfg.group} - -"
123+
];
124+
125+
systemd.services.peertube = {
126+
description = "Peertube";
127+
wantedBy = [ "multi-user.target" ];
128+
after = [ "network.target" "postgresql.service" "redis.service" ];
129+
wants = [ "postgresql.service" "redis.service" ];
130+
131+
environment.NODE_CONFIG_DIR = "${cfg.runtimeDir}/config";
132+
environment.NODE_ENV = "production";
133+
environment.HOME = cfg.package;
134+
135+
path = [ pkgs.nodejs pkgs.bashInteractive pkgs.ffmpeg pkgs.openssl pkgs.sudo pkgs.youtube-dl ];
136+
137+
script = ''
138+
install -m 0750 -d ${cfg.runtimeDir}/config
139+
ln -sf ${cfg.configFile} ${cfg.runtimeDir}/config/production.yaml
140+
exec npm start
141+
'';
142+
143+
serviceConfig = {
144+
User = cfg.user;
145+
Group = cfg.group;
146+
WorkingDirectory = cfg.package;
147+
StateDirectory = "peertube";
148+
StateDirectoryMode = "0750";
149+
PrivateTmp = true;
150+
ProtectHome = true;
151+
ProtectControlGroups = true;
152+
ProtectSystem = "full";
153+
Restart = "always";
154+
Type = "simple";
155+
TimeoutSec = 60;
156+
CapabilityBoundingSet = "~CAP_SYS_ADMIN";
157+
ExecStartPre = let script = pkgs.writeScript "peertube-pre-start.sh" ''
158+
#!/bin/sh
159+
set -e
160+
161+
if ! [ -e "${cfg.runtimeDir}/.first_run" ]; then
162+
set -v
163+
if [ -e "${cfg.runtimeDir}/.first_run_partial" ]; then
164+
echo "Warn: first run was interrupted"
165+
fi
166+
touch "${cfg.runtimeDir}/.first_run_partial"
167+
168+
echo "Running PeerTube's PostgreSQL initialization..."
169+
echo "PeerTube is known to work with PostgreSQL v12, if any error occurs, please check your version."
170+
171+
sudo -u postgres "${config.services.postgresql.package}/bin/createdb" -O ${cfg.database.user} -E UTF8 -T template0 ${cfg.database.name}
172+
sudo -u postgres "${config.services.postgresql.package}/bin/psql" -c "CREATE EXTENSION pg_trgm;" ${cfg.database.name}
173+
sudo -u postgres "${config.services.postgresql.package}/bin/psql" -c "CREATE EXTENSION unaccent;" ${cfg.database.name}
174+
175+
touch "${cfg.runtimeDir}/.first_run"
176+
rm "${cfg.runtimeDir}/.first_run_partial"
177+
fi
178+
'';
179+
in "+${script}";
180+
};
181+
182+
unitConfig.RequiresMountsFor = cfg.runtimeDir;
183+
};
184+
};
185+
}
186+

pkgs/servers/peertube/client.nix

+30
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
{ yarnModulesConfig, mkYarnModulesFixed, server, sources, version, nodejs, stdenv }:
2+
rec {
3+
modules = mkYarnModulesFixed rec {
4+
inherit version;
5+
pname = "peertube-client-yarn-modules";
6+
name = "${pname}-${version}";
7+
packageJSON = "${sources}/client/package.json";
8+
yarnLock = "${sources}/client/yarn.lock";
9+
pkgConfig = yarnModulesConfig;
10+
};
11+
dist = stdenv.mkDerivation {
12+
inherit version;
13+
pname = "peertube-client";
14+
src = sources;
15+
buildPhase = ''
16+
ln -s ${server.modules}/node_modules .
17+
cp -a ${modules}/node_modules client/
18+
chmod -R +w client/node_modules
19+
patchShebangs .
20+
npm run build:client
21+
'';
22+
23+
installPhase = ''
24+
mkdir $out
25+
cp -a client/dist $out
26+
'';
27+
28+
buildInputs = [ nodejs ];
29+
};
30+
}

pkgs/servers/peertube/default.nix

+121
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,121 @@
1+
{ light ? null, pkgs, stdenv, lib, fetchurl, fetchFromGitHub, callPackage
2+
, nodejs ? pkgs.nodejs-12_x
3+
, jq, youtube-dl, nodePackages, yarn2nix-moretea }:
4+
5+
let
6+
version = "3.0.1";
7+
8+
source = fetchFromGitHub {
9+
owner = "Chocobozzz";
10+
repo = "PeerTube";
11+
rev = "v${version}";
12+
sha256 = "bIXt5bQiBBlNDFXYzcdQA8qp4nse5epUx/XQOguDOX8=";
13+
};
14+
15+
patchedSource = stdenv.mkDerivation {
16+
pname = "peertube";
17+
inherit version;
18+
src = source;
19+
phases = [ "unpackPhase" "patchPhase" "installPhase" ];
20+
patches = [ ./fix_yarn_lock.patch ];
21+
installPhase = ''
22+
mkdir $out
23+
cp -a . $out/
24+
'';
25+
};
26+
yarnModulesConfig = {
27+
bcrypt = {
28+
buildInputs = [ nodePackages.node-pre-gyp ];
29+
30+
postInstall = let
31+
bcrypt_version = "5.0.0";
32+
bcrypt_lib = fetchurl {
33+
url = "https://github.com/kelektiv/node.bcrypt.js/releases/download/v${bcrypt_version}/bcrypt_lib-v${bcrypt_version}-napi-v3-linux-x64-glibc.tar.gz";
34+
sha256 = "0j3p2px1xb17sw3gpm8l4apljajxxfflal1yy552mhpzhi21wccn";
35+
};
36+
in ''
37+
if [ "${bcrypt_version}" != "$(cat package.json | ${jq}/bin/jq -r .version)" ]; then
38+
echo "Mismatching version please update bcrypt in derivation"
39+
false
40+
fi
41+
mkdir -p lib/binding && tar -C lib/binding -xf ${bcrypt_lib}
42+
patchShebangs ../node-pre-gyp
43+
npm run install
44+
'';
45+
};
46+
47+
utf-8-validate = {
48+
buildInputs = [ nodePackages.node-gyp-build ];
49+
};
50+
51+
youtube-dl = {
52+
postInstall = ''
53+
mkdir bin
54+
ln -s ${youtube-dl}/bin/youtube-dl bin/youtube-dl
55+
cat > bin/details <<EOF
56+
{"version":"${youtube-dl.version}","path":null,"exec":"youtube-dl"}
57+
EOF
58+
'';
59+
};
60+
};
61+
62+
mkYarnModulesFixed = args: (yarn2nix-moretea.mkYarnModules args).overrideAttrs(old: {
63+
# This hack permits to workaround the fact that the yarn.lock
64+
# file doesn't respect the semver requirements
65+
buildPhase = builtins.replaceStrings [" ./package.json"] [" /dev/null; cp deps/*/package.json ."] old.buildPhase;
66+
});
67+
68+
server = callPackage ./server.nix {
69+
inherit version yarnModulesConfig mkYarnModulesFixed;
70+
sources = patchedSource;
71+
};
72+
73+
client = callPackage ./client.nix {
74+
inherit server version yarnModulesConfig mkYarnModulesFixed;
75+
sources = patchedSource;
76+
};
77+
78+
in stdenv.mkDerivation rec {
79+
inherit version;
80+
pname = "peertube";
81+
src = patchedSource;
82+
83+
buildPhase = ''
84+
ln -s ${server.modules}/node_modules .
85+
rm -rf dist && cp -a ${server.dist}/dist dist
86+
rm -rf client/dist && cp -a ${client.dist}/dist client/
87+
'';
88+
89+
installPhase = ''
90+
mkdir $out
91+
cp -a * $out
92+
ln -s /tmp $out/.cache
93+
'';
94+
95+
meta = {
96+
description = "A free software to take back control of your videos";
97+
98+
longDescription = ''
99+
PeerTube aspires to be a decentralized and free/libre alternative to video
100+
broadcasting services.
101+
PeerTube is not meant to become a huge platform that would centralize
102+
videos from all around the world. Rather, it is a network of
103+
inter-connected small videos hosters.
104+
Anyone with a modicum of technical skills can host a PeerTube server, aka
105+
an instance. Each instance hosts its users and their videos. In this way,
106+
every instance is created, moderated and maintained independently by
107+
various administrators.
108+
You can still watch from your account videos hosted by other instances
109+
though if the administrator of your instance had previously connected it
110+
with other instances.
111+
'';
112+
113+
license = lib.licenses.agpl3Plus;
114+
115+
homepage = "https://joinpeertube.org/";
116+
platforms = lib.platforms.unix;
117+
118+
maintainers = with lib.maintainers; [ immae stevenroose ];
119+
};
120+
}
121+
+28
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
diff --git a/client/yarn.lock b/client/yarn.lock
2+
index d27cdaec8..26706a9fc 100644
3+
--- a/client/yarn.lock
4+
+++ b/client/yarn.lock
5+
@@ -5703,7 +5703,8 @@ http-errors@~1.7.2:
6+
7+
"http-node@github:feross/http-node#webtorrent":
8+
version "1.2.0"
9+
- resolved "https://codeload.github.com/feross/http-node/tar.gz/342ef8624495343ffd050bd0808b3750cf0e3974"
10+
+ resolved "https://codeload.github.com/feross/http-node/tar.gz/342ef8624495343ffd050bd0808b3750cf0e3974#33fa312d37f0000b17acdb1a5086565400419a13"
11+
+ integrity sha1-M/oxLTfwAAsXrNsaUIZWVABBmhM=
12+
dependencies:
13+
chrome-net "^3.3.3"
14+
freelist "^1.0.3"
15+
diff --git a/yarn.lock b/yarn.lock
16+
index 61a2ea05e..c742276c7 100644
17+
--- a/yarn.lock
18+
+++ b/yarn.lock
19+
@@ -3873,7 +3873,8 @@ http-errors@~1.7.2:
20+
21+
"http-node@github:feross/http-node#webtorrent":
22+
version "1.2.0"
23+
- resolved "https://codeload.github.com/feross/http-node/tar.gz/342ef8624495343ffd050bd0808b3750cf0e3974"
24+
+ resolved "https://codeload.github.com/feross/http-node/tar.gz/342ef8624495343ffd050bd0808b3750cf0e3974#33fa312d37f0000b17acdb1a5086565400419a13"
25+
+ integrity sha1-M/oxLTfwAAsXrNsaUIZWVABBmhM=
26+
dependencies:
27+
chrome-net "^3.3.3"
28+
freelist "^1.0.3"

0 commit comments

Comments
 (0)