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