]> git.immae.eu Git - perso/Immae/Config/Nix.git/blame - flakes/peertube/flake.nix
Squash changes containing private information
[perso/Immae/Config/Nix.git] / flakes / peertube / flake.nix
CommitLineData
ded643e1
IB
1{
2 description = "A free software to take back control of your videos";
3 inputs.myuids = {
1a64deeb 4 url = "path:../myuids";
ded643e1
IB
5 };
6 inputs.flake-utils.url = "github:numtide/flake-utils";
7 inputs.nixpkgs.url = "github:NixOS/nixpkgs";
8 inputs.peertube = {
9 url = "github:Chocobozzz/PeerTube/v3.0.1";
10 flake = false;
11 };
12
13 outputs = { self, myuids, nixpkgs, peertube, flake-utils }: flake-utils.lib.eachSystem ["x86_64-linux"] (system:
14 let
ded643e1
IB
15 pkgs = import nixpkgs { inherit system; overlays = [
16 (self: super: { nodejs = self.nodejs-12_x; })
17 ]; };
18 inherit (pkgs) callPackage stdenv jq youtube-dl fetchurl nodePackages yarn2nix-moretea;
19
20 patchedSource = stdenv.mkDerivation {
21 pname = "peertube";
5e2ec9fb 22 version = peertube.rev;
ded643e1
IB
23 src = peertube;
24 phases = [ "unpackPhase" "patchPhase" "installPhase" ];
25 patches = [ ./fix_yarn_lock.patch ];
26 installPhase = ''
27 mkdir $out
28 cp -a . $out/
29 '';
30 };
31 yarnModulesConfig = {
32 bcrypt = {
33 buildInputs = [ nodePackages.node-pre-gyp ];
34 postInstall = let
35 bcrypt_version = "5.0.0";
36 bcrypt_lib = fetchurl {
37 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";
38 sha256 = "0j3p2px1xb17sw3gpm8l4apljajxxfflal1yy552mhpzhi21wccn";
39 };
40 in
41 ''
42 if [ "${bcrypt_version}" != "$(cat package.json | ${jq}/bin/jq -r .version)" ]; then
43 echo "Mismatching version please update bcrypt in derivation"
44 false
45 fi
46 mkdir -p lib/binding && tar -C lib/binding -xf ${bcrypt_lib}
47 patchShebangs ../node-pre-gyp
48 npm run install
49 '';
50 };
51 utf-8-validate = {
52 buildInputs = [ nodePackages.node-gyp-build ];
53 };
54 youtube-dl = {
55 postInstall = ''
56 mkdir bin
57 ln -s ${youtube-dl}/bin/youtube-dl bin/youtube-dl
58 cat > bin/details <<EOF
59 {"version":"${youtube-dl.version}","path":null,"exec":"youtube-dl"}
60 EOF
61 '';
62 };
63 };
64 mkYarnModules' = args: (yarn2nix-moretea.mkYarnModules args).overrideAttrs(old: {
65 # This hack permits to workaround the fact that the yarn.lock
66 # file doesn't respect the semver requirements
67 buildPhase = builtins.replaceStrings [" ./package.json"] [" /dev/null; cp deps/*/package.json ."] old.buildPhase;
68 });
69
70 server = callPackage ./server.nix {
5e2ec9fb 71 inherit yarnModulesConfig mkYarnModules';
ded643e1
IB
72 sources = patchedSource;
73 };
74 client = callPackage ./client.nix {
5e2ec9fb 75 inherit server yarnModulesConfig mkYarnModules';
ded643e1
IB
76 sources = patchedSource;
77 };
78
79 in rec {
5e2ec9fb 80 packages.peertube = callPackage ./. { inherit server client; src = patchedSource; };
ded643e1
IB
81 defaultPackage = packages.peertube;
82 legacyPackages.peertube = packages.peertube;
83 checks = {
84 build = defaultPackage;
85 } // pkgs.lib.optionalAttrs (builtins.elem system pkgs.lib.systems.doubles.linux) {
86 test =
87 let testing = import (nixpkgs + "/nixos/lib/testing-python.nix") { inherit system; };
88 in testing.makeTest {
89 nodes = {
90 client = { pkgs, ... }: {};
91
92 server = { pkgs, ... }: {
93 imports = [ self.nixosModule ];
94 config.networking.firewall.allowedTCPPorts = [ 8888 ];
95 config.services.redis.enable = true;
96 config.services.postgresql = {
97 enable = true;
98 initialScript = pkgs.writeText "peertube.sql" ''
99 CREATE ROLE "peertube" WITH LOGIN PASSWORD 'peertube';
100 CREATE DATABASE "peertube_prod" WITH OWNER "peertube"
101 TEMPLATE template0
102 LC_COLLATE = "C"
103 LC_CTYPE = "C";
104 \c peertube_prod
105 CREATE EXTENSION unaccent;
106 CREATE EXTENSION pg_trgm;
107 '';
108 };
109 config.services.peertube.enable = true;
110 config.services.peertube.configFile = pkgs.writeText "peertube.conf" ''
111 listen:
112 hostname: '0.0.0.0'
113 port: 8888
114 webserver:
115 https: false
116 hostname: 'localhost.tld'
117 port: 8888
118 database:
119 hostname: 'localhost'
120 port: 5432
121 suffix: '_prod'
122 username: 'peertube'
123 password: 'peertube'
124 pool:
125 max: 5
126 redis:
127 socket: 'localhost'
128 auth: null
129 db: 0
130 storage:
131 tmp: '/var/lib/peertube/storage/tmp/'
132 avatars: '/var/lib/peertube/storage/avatars/'
133 videos: '/var/lib/peertube/storage/videos/'
134 streaming_playlists: '/var/lib/peertube/storage/streaming-playlists/'
135 redundancy: '/var/lib/peertube/storage/videos/'
136 logs: '/var/lib/peertube/storage/logs/'
137 previews: '/var/lib/peertube/storage/previews/'
138 thumbnails: '/var/lib/peertube/storage/thumbnails/'
139 torrents: '/var/lib/peertube/storage/torrents/'
140 captions: '/var/lib/peertube/storage/captions/'
141 cache: '/var/lib/peertube/storage/cache/'
142 plugins: '/var/lib/peertube/storage/plugins/'
143 client_overrides: '/var/lib/peertube/storage/client-overrides/'
144 '';
145 };
146 };
147 testScript = ''
148 start_all()
149 server.wait_for_unit("peertube.service")
150 server.wait_for_open_port(8888)
151 client.succeed("curl http://server:8888")
152 client.succeed("curl http://server:8888/client/fr-FR/index.html")
153 '';
154 };
155 };
156 }
5e2ec9fb
IB
157 ) // rec {
158 overlays = {
159 peertube = final: prev: {
160 peertube = self.defaultPackage."${final.system}";
161 };
162 };
163 overlay = overlays.peertube;
ded643e1
IB
164 nixosModule = { lib, pkgs, config, ... }:
165 let
166 name = "peertube";
1a64deeb 167 cfg = config.immaeServices.peertube;
ded643e1
IB
168 in
169 {
1a64deeb 170 options.immaeServices.peertube = {
ded643e1
IB
171 enable = lib.mkEnableOption "Enable Peertube’s service";
172 user = lib.mkOption {
173 type = lib.types.str;
174 default = name;
175 description = "User account under which Peertube runs";
176 };
177 group = lib.mkOption {
178 type = lib.types.str;
179 default = name;
180 description = "Group under which Peertube runs";
181 };
182 dataDir = lib.mkOption {
183 type = lib.types.path;
184 default = "/var/lib/${name}";
185 description = ''
186 The directory where Peertube stores its data.
187 '';
188 };
189 configFile = lib.mkOption {
190 type = lib.types.path;
191 description = ''
192 The configuration file path for Peertube.
193 '';
194 };
195 package = lib.mkOption {
196 type = lib.types.package;
f4721555 197 default = pkgs.peertube;
ded643e1
IB
198 description = ''
199 Peertube package to use.
200 '';
201 };
202 # Output variables
203 systemdStateDirectory = lib.mkOption {
204 type = lib.types.str;
205 # Use ReadWritePaths= instead if varDir is outside of /var/lib
206 default = assert lib.strings.hasPrefix "/var/lib/" cfg.dataDir;
207 lib.strings.removePrefix "/var/lib/" cfg.dataDir;
208 description = ''
209 Adjusted Peertube data directory for systemd
210 '';
211 readOnly = true;
212 };
213 };
214
215 config = lib.mkIf cfg.enable {
f4721555 216 nixpkgs.overlays = [ self.overlay ];
ded643e1
IB
217 users.users = lib.optionalAttrs (cfg.user == name) {
218 "${name}" = {
219 uid = myuids.lib.uids.peertube;
220 group = cfg.group;
221 description = "Peertube user";
222 home = cfg.dataDir;
223 useDefaultShell = true;
224 };
225 };
226 users.groups = lib.optionalAttrs (cfg.group == name) {
227 "${name}" = {
228 gid = myuids.lib.gids.peertube;
229 };
230 };
231
232 systemd.services.peertube = {
233 description = "Peertube";
234 wantedBy = [ "multi-user.target" ];
235 after = [ "network.target" "postgresql.service" ];
236 wants = [ "postgresql.service" ];
237
238 environment.NODE_CONFIG_DIR = "${cfg.dataDir}/config";
239 environment.NODE_ENV = "production";
1a64deeb
IB
240 environment.NPM_CONFIG_LOGS_DIR = "${cfg.dataDir}/npm_logs";
241 environment.NPM_CONFIG_CACHE = "${cfg.dataDir}/npm_cache";
ded643e1
IB
242 environment.HOME = cfg.package;
243
3d11eafc 244 path = [ pkgs.nodejs pkgs.yarn pkgs.bashInteractive pkgs.ffmpeg pkgs.openssl ];
ded643e1
IB
245
246 script = ''
247 install -m 0750 -d ${cfg.dataDir}/config
248 ln -sf ${cfg.configFile} ${cfg.dataDir}/config/production.yaml
249 ln -sf ${cfg.package}/config/default.yaml ${cfg.dataDir}/config/default.yaml
250 exec npm run start
251 '';
252
253 serviceConfig = {
254 User = cfg.user;
255 Group = cfg.group;
256 WorkingDirectory = cfg.package;
257 StateDirectory = cfg.systemdStateDirectory;
258 StateDirectoryMode = 0750;
259 PrivateTmp = true;
260 ProtectHome = true;
261 ProtectControlGroups = true;
262 Restart = "always";
263 Type = "simple";
264 TimeoutSec = 60;
265 };
266
267 unitConfig.RequiresMountsFor = cfg.dataDir;
268 };
269 };
270 };
271
272 };
273}