Merge pull request #273769 from Izorkin/update-peertube

peertube: 5.2.1 -> 6.0.3

Changed files
+230 -190
nixos
modules
services
web-apps
tests
web-apps
pkgs
servers
peertube
+143 -147
nixos/modules/services/web-apps/peertube.nix
···
eval -- "\$@"
'';
-
peertubeCli = pkgs.writeShellScriptBin "peertube" ''
-
node ~/dist/server/tools/peertube.js $@
'';
-
nginxCommonHeaders = lib.optionalString cfg.enableWebHttps ''
-
add_header Strict-Transport-Security 'max-age=63072000; includeSubDomains';
-
'' + lib.optionalString config.services.nginx.virtualHosts.${cfg.localDomain}.http3 ''
-
add_header Alt-Svc 'h3=":443"; ma=86400';
-
'' + ''
-
add_header Access-Control-Allow-Origin '*';
-
add_header Access-Control-Allow-Methods 'GET, OPTIONS';
-
add_header Access-Control-Allow-Headers 'Range,DNT,X-CustomHeader,Keep-Alive,User-Agent,X-Requested-With,If-Modified-Since,Cache-Control,Content-Type';
'';
in {
···
}
];
services.peertube.settings = lib.mkMerge [
{
listen = {
···
tmp_persistent = lib.mkDefault "/var/lib/peertube/storage/tmp_persistent/";
bin = lib.mkDefault "/var/lib/peertube/storage/bin/";
avatars = lib.mkDefault "/var/lib/peertube/storage/avatars/";
-
videos = lib.mkDefault "/var/lib/peertube/storage/videos/";
streaming_playlists = lib.mkDefault "/var/lib/peertube/storage/streaming-playlists/";
redundancy = lib.mkDefault "/var/lib/peertube/storage/redundancy/";
logs = lib.mkDefault "/var/lib/peertube/storage/logs/";
previews = lib.mkDefault "/var/lib/peertube/storage/previews/";
thumbnails = lib.mkDefault "/var/lib/peertube/storage/thumbnails/";
torrents = lib.mkDefault "/var/lib/peertube/storage/torrents/";
captions = lib.mkDefault "/var/lib/peertube/storage/captions/";
cache = lib.mkDefault "/var/lib/peertube/storage/cache/";
···
environment = env;
-
path = with pkgs; [ bashInteractive ffmpeg nodejs_18 openssl yarn python3 ];
script = ''
#!/bin/sh
···
ln -sf ${cfg.package}/config/default.yaml /var/lib/peertube/config/default.yaml
ln -sf ${cfg.package}/client/dist -T /var/lib/peertube/www/client
ln -sf ${cfg.settings.storage.client_overrides} -T /var/lib/peertube/www/client-overrides
-
npm start
'';
serviceConfig = {
Type = "simple";
···
services.nginx = lib.mkIf cfg.configureNginx {
enable = true;
virtualHosts."${cfg.localDomain}" = {
root = "/var/lib/peertube/www";
···
priority = 1110;
};
-
locations."= /api/v1/videos/upload-resumable" = {
tryFiles = "/dev/null @api";
priority = 1120;
extraConfig = ''
-
client_max_body_size 0;
-
proxy_request_buffering off;
-
'';
};
locations."~ ^/api/v1/videos/(upload|([^/]+/studio/edit))$" = {
···
priority = 1130;
extraConfig = ''
-
client_max_body_size 12G;
-
add_header X-File-Maximum-Size 8G always;
-
'' + lib.optionalString cfg.enableWebHttps ''
-
add_header Strict-Transport-Security 'max-age=63072000; includeSubDomains';
-
'' + lib.optionalString config.services.nginx.virtualHosts.${cfg.localDomain}.http3 ''
-
add_header Alt-Svc 'h3=":443"; ma=86400';
-
'';
};
locations."~ ^/api/v1/runners/jobs/[^/]+/(update|success)$" = {
···
priority = 1135;
extraConfig = ''
-
client_max_body_size 12G;
-
add_header X-File-Maximum-Size 8G always;
-
'' + lib.optionalString cfg.enableWebHttps ''
-
add_header Strict-Transport-Security 'max-age=63072000; includeSubDomains';
-
'' + lib.optionalString config.services.nginx.virtualHosts.${cfg.localDomain}.http3 ''
-
add_header Alt-Svc 'h3=":443"; ma=86400';
-
'';
};
locations."~ ^/api/v1/(videos|video-playlists|video-channels|users/me)" = {
···
priority = 1140;
extraConfig = ''
-
client_max_body_size 6M;
-
add_header X-File-Maximum-Size 4M always;
-
'' + lib.optionalString cfg.enableWebHttps ''
-
add_header Strict-Transport-Security 'max-age=63072000; includeSubDomains';
-
'' + lib.optionalString config.services.nginx.virtualHosts.${cfg.localDomain}.http3 ''
-
add_header Alt-Svc 'h3=":443"; ma=86400';
-
'';
};
locations."@api" = {
-
proxyPass = "http://127.0.0.1:${toString cfg.listenHttp}";
priority = 1150;
extraConfig = ''
-
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
-
proxy_set_header Host $host;
-
proxy_set_header X-Real-IP $remote_addr;
-
proxy_connect_timeout 10m;
-
proxy_send_timeout 10m;
-
proxy_read_timeout 10m;
-
client_max_body_size 100k;
-
send_timeout 10m;
-
'';
};
# Websocket
···
priority = 1220;
extraConfig = ''
-
proxy_read_timeout 15m;
'';
};
···
};
locations."@api_websocket" = {
-
proxyPass = "http://127.0.0.1:${toString cfg.listenHttp}";
priority = 1240;
extraConfig = ''
-
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
-
proxy_set_header Host $host;
-
proxy_set_header X-Real-IP $remote_addr;
-
proxy_set_header Upgrade $http_upgrade;
-
proxy_set_header Connection 'upgrade';
-
proxy_http_version 1.1;
-
'';
};
# Bypass PeerTube for performance reasons.
locations."~ ^/client/(assets/images/(icons/icon-36x36\.png|icons/icon-48x48\.png|icons/icon-72x72\.png|icons/icon-96x96\.png|icons/icon-144x144\.png|icons/icon-192x192\.png|icons/icon-512x512\.png|logo\.svg|favicon\.png|default-playlist\.jpg|default-avatar-account\.png|default-avatar-account-48x48\.png|default-avatar-video-channel\.png|default-avatar-video-channel-48x48\.png))$" = {
tryFiles = "/client-overrides/$1 /client/$1 $1";
priority = 1310;
};
locations."~ ^/client/(.*\.(js|css|png|svg|woff2|otf|ttf|woff|eot))$" = {
alias = "${cfg.package}/client/dist/$1";
priority = 1320;
extraConfig = ''
-
add_header Cache-Control 'public, max-age=604800, immutable';
-
'' + lib.optionalString cfg.enableWebHttps ''
-
add_header Strict-Transport-Security 'max-age=63072000; includeSubDomains';
-
'' + lib.optionalString config.services.nginx.virtualHosts.${cfg.localDomain}.http3 ''
-
add_header Alt-Svc 'h3=":443"; ma=86400';
-
'';
};
locations."^~ /download/" = {
-
proxyPass = "http://127.0.0.1:${toString cfg.listenHttp}";
priority = 1410;
extraConfig = ''
-
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
-
proxy_set_header Host $host;
-
proxy_set_header X-Real-IP $remote_addr;
-
proxy_limit_rate 5M;
-
'';
};
-
locations."^~ /static/streaming-playlists/private/" = {
-
proxyPass = "http://127.0.0.1:${toString cfg.listenHttp}";
priority = 1420;
extraConfig = ''
-
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
-
proxy_set_header Host $host;
-
proxy_set_header X-Real-IP $remote_addr;
-
proxy_limit_rate 5M;
-
'';
};
locations."^~ /static/web-videos/private/" = {
-
proxyPass = "http://127.0.0.1:${toString cfg.listenHttp}";
priority = 1430;
extraConfig = ''
-
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
-
proxy_set_header Host $host;
-
proxy_set_header X-Real-IP $remote_addr;
-
proxy_limit_rate 5M;
-
'';
};
locations."^~ /static/webseed/private/" = {
-
proxyPass = "http://127.0.0.1:${toString cfg.listenHttp}";
priority = 1440;
extraConfig = ''
-
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
-
proxy_set_header Host $host;
-
proxy_set_header X-Real-IP $remote_addr;
-
proxy_limit_rate 5M;
-
'';
};
locations."^~ /static/redundancy/" = {
···
root = cfg.settings.storage.redundancy;
priority = 1450;
extraConfig = ''
-
set $peertube_limit_rate 800k;
if ($request_uri ~ -fragmented.mp4$) {
-
set $peertube_limit_rate 5M;
}
if ($request_method = 'OPTIONS') {
${nginxCommonHeaders}
-
add_header Access-Control-Max-Age 1728000;
-
add_header Content-Type 'text/plain charset=UTF-8';
-
add_header Content-Length 0;
-
return 204;
}
if ($request_method = 'GET') {
${nginxCommonHeaders}
-
access_log off;
}
-
aio threads;
-
sendfile on;
-
sendfile_max_chunk 1M;
-
limit_rate $peertube_limit_rate;
-
limit_rate_after 5M;
-
rewrite ^/static/redundancy/(.*)$ /$1 break;
'';
};
···
root = cfg.settings.storage.streaming_playlists;
priority = 1460;
extraConfig = ''
-
set $peertube_limit_rate 800k;
if ($request_uri ~ -fragmented.mp4$) {
-
set $peertube_limit_rate 5M;
}
if ($request_method = 'OPTIONS') {
${nginxCommonHeaders}
-
add_header Access-Control-Max-Age 1728000;
-
add_header Content-Type 'text/plain charset=UTF-8';
-
add_header Content-Length 0;
-
return 204;
}
if ($request_method = 'GET') {
${nginxCommonHeaders}
-
access_log off;
}
-
aio threads;
-
sendfile on;
-
sendfile_max_chunk 1M;
-
limit_rate $peertube_limit_rate;
-
limit_rate_after 5M;
-
rewrite ^/static/streaming-playlists/(.*)$ /$1 break;
'';
};
locations."^~ /static/web-videos/" = {
tryFiles = "$uri @api";
-
root = cfg.settings.storage.streaming_playlists;
priority = 1470;
extraConfig = ''
-
set $peertube_limit_rate 800k;
if ($request_uri ~ -fragmented.mp4$) {
-
set $peertube_limit_rate 5M;
}
if ($request_method = 'OPTIONS') {
${nginxCommonHeaders}
-
add_header Access-Control-Max-Age 1728000;
-
add_header Content-Type 'text/plain charset=UTF-8';
-
add_header Content-Length 0;
-
return 204;
}
if ($request_method = 'GET') {
${nginxCommonHeaders}
-
access_log off;
}
-
aio threads;
-
sendfile on;
-
sendfile_max_chunk 1M;
-
limit_rate $peertube_limit_rate;
-
limit_rate_after 5M;
-
rewrite ^/static/streaming-playlists/(.*)$ /$1 break;
'';
};
locations."^~ /static/webseed/" = {
tryFiles = "$uri @api";
-
root = cfg.settings.storage.videos;
priority = 1480;
extraConfig = ''
-
set $peertube_limit_rate 800k;
if ($request_uri ~ -fragmented.mp4$) {
-
set $peertube_limit_rate 5M;
}
if ($request_method = 'OPTIONS') {
${nginxCommonHeaders}
-
add_header Access-Control-Max-Age 1728000;
-
add_header Content-Type 'text/plain charset=UTF-8';
-
add_header Content-Length 0;
-
return 204;
}
if ($request_method = 'GET') {
${nginxCommonHeaders}
-
access_log off;
}
-
aio threads;
-
sendfile on;
-
sendfile_max_chunk 1M;
-
limit_rate $peertube_limit_rate;
-
limit_rate_after 5M;
-
rewrite ^/static/webseed/(.*)$ /$1 break;
'';
};
-
-
extraConfig = lib.optionalString cfg.enableWebHttps ''
-
add_header Strict-Transport-Security 'max-age=63072000; includeSubDomains';
-
'';
};
};
···
home = cfg.package;
};
})
-
(lib.attrsets.setAttrByPath [ cfg.user "packages" ] [ cfg.package peertubeEnv peertubeCli pkgs.ffmpeg pkgs.nodejs_18 pkgs.yarn ])
(lib.mkIf cfg.redis.enableUnixSocket {${config.services.peertube.user}.extraGroups = [ "redis-peertube" ];})
];
···
eval -- "\$@"
'';
+
nginxCommonHeaders = lib.optionalString config.services.nginx.virtualHosts.${cfg.localDomain}.forceSSL ''
+
add_header Strict-Transport-Security 'max-age=31536000';
+
'' + lib.optionalString (config.services.nginx.virtualHosts.${cfg.localDomain}.quic && config.services.nginx.virtualHosts.${cfg.localDomain}.http3) ''
+
add_header Alt-Svc 'h3=":$server_port"; ma=604800';
'';
+
nginxCommonHeadersExtra = ''
+
add_header Access-Control-Allow-Origin '*';
+
add_header Access-Control-Allow-Methods 'GET, OPTIONS';
+
add_header Access-Control-Allow-Headers 'Range,DNT,X-CustomHeader,Keep-Alive,User-Agent,X-Requested-With,If-Modified-Since,Cache-Control,Content-Type';
'';
in {
···
}
];
+
environment.systemPackages = [ cfg.package.cli ];
+
services.peertube.settings = lib.mkMerge [
{
listen = {
···
tmp_persistent = lib.mkDefault "/var/lib/peertube/storage/tmp_persistent/";
bin = lib.mkDefault "/var/lib/peertube/storage/bin/";
avatars = lib.mkDefault "/var/lib/peertube/storage/avatars/";
+
web_videos = lib.mkDefault "/var/lib/peertube/storage/web-videos/";
streaming_playlists = lib.mkDefault "/var/lib/peertube/storage/streaming-playlists/";
redundancy = lib.mkDefault "/var/lib/peertube/storage/redundancy/";
logs = lib.mkDefault "/var/lib/peertube/storage/logs/";
previews = lib.mkDefault "/var/lib/peertube/storage/previews/";
thumbnails = lib.mkDefault "/var/lib/peertube/storage/thumbnails/";
+
storyboards = lib.mkDefault "/var/lib/peertube/storage/storyboards/";
torrents = lib.mkDefault "/var/lib/peertube/storage/torrents/";
captions = lib.mkDefault "/var/lib/peertube/storage/captions/";
cache = lib.mkDefault "/var/lib/peertube/storage/cache/";
···
environment = env;
+
path = with pkgs; [ nodejs_18 yarn ffmpeg-headless openssl ];
script = ''
#!/bin/sh
···
ln -sf ${cfg.package}/config/default.yaml /var/lib/peertube/config/default.yaml
ln -sf ${cfg.package}/client/dist -T /var/lib/peertube/www/client
ln -sf ${cfg.settings.storage.client_overrides} -T /var/lib/peertube/www/client-overrides
+
node dist/server
'';
serviceConfig = {
Type = "simple";
···
services.nginx = lib.mkIf cfg.configureNginx {
enable = true;
+
upstreams."peertube".servers = {
+
"127.0.0.1:${toString cfg.listenHttp}".fail_timeout = "0";
+
};
virtualHosts."${cfg.localDomain}" = {
root = "/var/lib/peertube/www";
···
priority = 1110;
};
+
locations."~ ^/api/v1/videos/(upload-resumable|([^/]+/source/replace-resumable))$" = {
tryFiles = "/dev/null @api";
priority = 1120;
extraConfig = ''
+
client_max_body_size 0;
+
proxy_request_buffering off;
+
'' + nginxCommonHeaders;
};
locations."~ ^/api/v1/videos/(upload|([^/]+/studio/edit))$" = {
···
priority = 1130;
extraConfig = ''
+
limit_except POST HEAD { deny all; }
+
+
client_max_body_size 12G;
+
add_header X-File-Maximum-Size 8G always;
+
'' + nginxCommonHeaders;
};
locations."~ ^/api/v1/runners/jobs/[^/]+/(update|success)$" = {
···
priority = 1135;
extraConfig = ''
+
client_max_body_size 12G;
+
add_header X-File-Maximum-Size 8G always;
+
'' + nginxCommonHeaders;
};
locations."~ ^/api/v1/(videos|video-playlists|video-channels|users/me)" = {
···
priority = 1140;
extraConfig = ''
+
client_max_body_size 6M;
+
add_header X-File-Maximum-Size 4M always;
+
'' + nginxCommonHeaders;
};
locations."@api" = {
+
proxyPass = "http://peertube";
priority = 1150;
extraConfig = ''
+
proxy_set_header Host $host;
+
proxy_set_header X-Real-IP $remote_addr;
+
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
+
proxy_connect_timeout 10m;
+
proxy_send_timeout 10m;
+
proxy_read_timeout 10m;
+
client_max_body_size 100k;
+
send_timeout 10m;
+
''+ nginxCommonHeaders;
};
# Websocket
···
priority = 1220;
extraConfig = ''
+
proxy_read_timeout 15m;
'';
};
···
};
locations."@api_websocket" = {
+
proxyPass = "http://peertube";
priority = 1240;
extraConfig = ''
+
proxy_http_version 1.1;
+
proxy_set_header Upgrade $http_upgrade;
+
proxy_set_header Connection 'upgrade';
+
proxy_set_header Host $host;
+
proxy_set_header X-Real-IP $remote_addr;
+
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
+
'' + nginxCommonHeaders;
};
# Bypass PeerTube for performance reasons.
locations."~ ^/client/(assets/images/(icons/icon-36x36\.png|icons/icon-48x48\.png|icons/icon-72x72\.png|icons/icon-96x96\.png|icons/icon-144x144\.png|icons/icon-192x192\.png|icons/icon-512x512\.png|logo\.svg|favicon\.png|default-playlist\.jpg|default-avatar-account\.png|default-avatar-account-48x48\.png|default-avatar-video-channel\.png|default-avatar-video-channel-48x48\.png))$" = {
tryFiles = "/client-overrides/$1 /client/$1 $1";
priority = 1310;
+
+
extraConfig = nginxCommonHeaders;
};
locations."~ ^/client/(.*\.(js|css|png|svg|woff2|otf|ttf|woff|eot))$" = {
alias = "${cfg.package}/client/dist/$1";
priority = 1320;
extraConfig = ''
+
add_header Cache-Control 'public, max-age=604800, immutable';
+
'' + nginxCommonHeaders;
};
locations."^~ /download/" = {
+
proxyPass = "http://peertube";
priority = 1410;
extraConfig = ''
+
proxy_set_header Host $host;
+
proxy_set_header X-Real-IP $remote_addr;
+
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
+
proxy_limit_rate 5M;
+
'' + nginxCommonHeaders;
};
+
locations."^~ /static/streaming-playlists/hls/private/" = {
+
proxyPass = "http://peertube";
priority = 1420;
extraConfig = ''
+
proxy_set_header Host $host;
+
proxy_set_header X-Real-IP $remote_addr;
+
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
+
proxy_limit_rate 5M;
+
'' + nginxCommonHeaders;
};
locations."^~ /static/web-videos/private/" = {
+
proxyPass = "http://peertube";
priority = 1430;
extraConfig = ''
+
proxy_set_header Host $host;
+
proxy_set_header X-Real-IP $remote_addr;
+
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
+
proxy_limit_rate 5M;
+
'' + nginxCommonHeaders;
};
locations."^~ /static/webseed/private/" = {
+
proxyPass = "http://peertube";
priority = 1440;
extraConfig = ''
+
proxy_set_header Host $host;
+
proxy_set_header X-Real-IP $remote_addr;
+
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
+
proxy_limit_rate 5M;
+
'' + nginxCommonHeaders;
};
locations."^~ /static/redundancy/" = {
···
root = cfg.settings.storage.redundancy;
priority = 1450;
extraConfig = ''
+
set $peertube_limit_rate 800k;
if ($request_uri ~ -fragmented.mp4$) {
+
set $peertube_limit_rate 5M;
}
if ($request_method = 'OPTIONS') {
${nginxCommonHeaders}
+
${nginxCommonHeadersExtra}
+
add_header Access-Control-Max-Age 1728000;
+
add_header Content-Type 'text/plain charset=UTF-8';
+
add_header Content-Length 0;
+
return 204;
}
if ($request_method = 'GET') {
${nginxCommonHeaders}
+
${nginxCommonHeadersExtra}
+
access_log off;
}
+
aio threads;
+
sendfile on;
+
sendfile_max_chunk 1M;
+
limit_rate $peertube_limit_rate;
+
limit_rate_after 5M;
+
rewrite ^/static/redundancy/(.*)$ /$1 break;
'';
};
···
root = cfg.settings.storage.streaming_playlists;
priority = 1460;
extraConfig = ''
+
set $peertube_limit_rate 800k;
if ($request_uri ~ -fragmented.mp4$) {
+
set $peertube_limit_rate 5M;
}
if ($request_method = 'OPTIONS') {
${nginxCommonHeaders}
+
${nginxCommonHeadersExtra}
+
add_header Access-Control-Max-Age 1728000;
+
add_header Content-Type 'text/plain charset=UTF-8';
+
add_header Content-Length 0;
+
return 204;
}
if ($request_method = 'GET') {
${nginxCommonHeaders}
+
${nginxCommonHeadersExtra}
+
access_log off;
}
+
aio threads;
+
sendfile on;
+
sendfile_max_chunk 1M;
+
limit_rate $peertube_limit_rate;
+
limit_rate_after 5M;
+
rewrite ^/static/streaming-playlists/(.*)$ /$1 break;
'';
};
locations."^~ /static/web-videos/" = {
tryFiles = "$uri @api";
+
root = cfg.settings.storage.web_videos;
priority = 1470;
extraConfig = ''
+
set $peertube_limit_rate 800k;
if ($request_uri ~ -fragmented.mp4$) {
+
set $peertube_limit_rate 5M;
}
if ($request_method = 'OPTIONS') {
${nginxCommonHeaders}
+
${nginxCommonHeadersExtra}
+
add_header Access-Control-Max-Age 1728000;
+
add_header Content-Type 'text/plain charset=UTF-8';
+
add_header Content-Length 0;
+
return 204;
}
if ($request_method = 'GET') {
${nginxCommonHeaders}
+
${nginxCommonHeadersExtra}
+
access_log off;
}
+
aio threads;
+
sendfile on;
+
sendfile_max_chunk 1M;
+
limit_rate $peertube_limit_rate;
+
limit_rate_after 5M;
+
rewrite ^/static/web-videos/(.*)$ /$1 break;
'';
};
locations."^~ /static/webseed/" = {
tryFiles = "$uri @api";
+
root = cfg.settings.storage.web_videos;
priority = 1480;
extraConfig = ''
+
set $peertube_limit_rate 800k;
if ($request_uri ~ -fragmented.mp4$) {
+
set $peertube_limit_rate 5M;
}
if ($request_method = 'OPTIONS') {
${nginxCommonHeaders}
+
${nginxCommonHeadersExtra}
+
add_header Access-Control-Max-Age 1728000;
+
add_header Content-Type 'text/plain charset=UTF-8';
+
add_header Content-Length 0;
+
return 204;
}
if ($request_method = 'GET') {
${nginxCommonHeaders}
+
${nginxCommonHeadersExtra}
+
access_log off;
}
+
aio threads;
+
sendfile on;
+
sendfile_max_chunk 1M;
+
limit_rate $peertube_limit_rate;
+
limit_rate_after 5M;
+
rewrite ^/static/webseed/(.*)$ /web-videos/$1 break;
'';
};
};
};
···
home = cfg.package;
};
})
+
(lib.attrsets.setAttrByPath [ cfg.user "packages" ] [ peertubeEnv pkgs.nodejs_18 pkgs.yarn pkgs.ffmpeg-headless ])
(lib.mkIf cfg.redis.enableUnixSocket {${config.services.peertube.user}.extraGroups = [ "redis-peertube" ];})
];
+19 -9
nixos/tests/web-apps/peertube.nix
···
services.postgresql = {
enable = true;
enableTCPIP = true;
authentication = ''
-
hostnossl peertube_local peertube_test 192.168.2.11/32 md5
'';
initialScript = pkgs.writeText "postgresql_init.sql" ''
CREATE ROLE peertube_test LOGIN PASSWORD '0gUN0C1mgST6czvjZ8T9';
-
CREATE DATABASE peertube_local TEMPLATE template0 ENCODING UTF8;
-
GRANT ALL PRIVILEGES ON DATABASE peertube_local TO peertube_test;
-
\connect peertube_local
-
CREATE EXTENSION IF NOT EXISTS pg_trgm;
-
CREATE EXTENSION IF NOT EXISTS unaccent;
'';
};
···
server = { pkgs, ... }: {
environment = {
etc = {
"peertube/secrets-peertube".text = ''
063d9c60d519597acef26003d5ecc32729083965d09181ef3949200cbe5f09ee
'';
···
localDomain = "peertube.local";
enableWebHttps = false;
secrets = {
secretsFile = "/etc/peertube/secrets-peertube";
};
database = {
host = "192.168.2.10";
-
name = "peertube_local";
user = "peertube_test";
passwordFile = "/etc/peertube/password-posgressql-db";
};
···
};
client = {
-
environment.systemPackages = [ pkgs.jq ];
networking = {
interfaces.eth1 = {
ipv4.addresses = [
···
client.succeed("curl --fail http://peertube.local:9000/api/v1/config/about | jq -r '.instance.name' | grep 'PeerTube\ Test\ Server'")
# Check PeerTube CLI version
-
assert "${pkgs.peertube.version}" in server.succeed('su - peertube -s /bin/sh -c "peertube --version"')
client.shutdown()
server.shutdown()
···
services.postgresql = {
enable = true;
enableTCPIP = true;
+
ensureDatabases = [ "peertube_test" ];
+
ensureUsers = [
+
{
+
name = "peertube_test";
+
ensureDBOwnership = true;
+
}
+
];
authentication = ''
+
hostnossl peertube_test peertube_test 192.168.2.11/32 md5
'';
initialScript = pkgs.writeText "postgresql_init.sql" ''
CREATE ROLE peertube_test LOGIN PASSWORD '0gUN0C1mgST6czvjZ8T9';
'';
};
···
server = { pkgs, ... }: {
environment = {
etc = {
+
"peertube/password-init-root".text = ''
+
PT_INITIAL_ROOT_PASSWORD=zw4SqYVdcsXUfRX8aaFX
+
'';
"peertube/secrets-peertube".text = ''
063d9c60d519597acef26003d5ecc32729083965d09181ef3949200cbe5f09ee
'';
···
localDomain = "peertube.local";
enableWebHttps = false;
+
serviceEnvironmentFile = "/etc/peertube/password-init-root";
+
secrets = {
secretsFile = "/etc/peertube/secrets-peertube";
};
database = {
host = "192.168.2.10";
+
name = "peertube_test";
user = "peertube_test";
passwordFile = "/etc/peertube/password-posgressql-db";
};
···
};
client = {
+
environment.systemPackages = [ pkgs.jq pkgs.peertube.cli ];
networking = {
interfaces.eth1 = {
ipv4.addresses = [
···
client.succeed("curl --fail http://peertube.local:9000/api/v1/config/about | jq -r '.instance.name' | grep 'PeerTube\ Test\ Server'")
# Check PeerTube CLI version
+
client.succeed('peertube-cli auth add -u "http://peertube.local:9000" -U "root" --password "zw4SqYVdcsXUfRX8aaFX"')
+
client.succeed('peertube-cli auth list | grep "http://peertube.local:9000"')
+
client.succeed('peertube-cli auth del "http://peertube.local:9000"')
+
client.fail('peertube-cli auth list | grep "http://peertube.local:9000"')
client.shutdown()
server.shutdown()
+68 -34
pkgs/servers/peertube/default.nix
···
x86_64-linux = {
arch = "linux-x64";
libc = "glibc";
-
hash = "sha256-I1ceMi7h6flvKBmMIU1qjAU1S6z5MzguHDul3g1zMKw=";
};
aarch64-linux = {
arch = "linux-arm64";
libc = "glibc";
-
hash = "sha256-q8BR7kILYV8i8ozDkpcuKarf4s1TgRqOrUeLqjdWEQ0=";
};
x86_64-darwin = {
arch = "darwin-x64";
libc = "unknown";
-
hash = "sha256-ONnXtRxcYFuFz+rmVTg+yEKe6J/vfKahX2i6k8dQStg=";
};
aarch64-darwin = {
arch = "darwin-arm64";
libc = "unknown";
-
hash = "sha256-VesAcT/IF2cvJVncJoqZcAvFxw32SN70C60GLU2kmVI=";
};
};
bcryptAttrs = bcryptHostPlatformAttrs."${stdenv.hostPlatform.system}" or
(throw "Unsupported architecture: ${stdenv.hostPlatform.system}");
-
bcryptVersion = "5.1.0";
bcryptLib = fetchurl {
url = "https://github.com/kelektiv/node.bcrypt.js/releases/download/v${bcryptVersion}/bcrypt_lib-v${bcryptVersion}-napi-v3-${bcryptAttrs.arch}-${bcryptAttrs.libc}.tar.gz";
inherit (bcryptAttrs) hash;
···
in
stdenv.mkDerivation rec {
pname = "peertube";
-
version = "5.2.1";
src = fetchFromGitHub {
owner = "Chocobozzz";
repo = "PeerTube";
rev = "v${version}";
-
hash = "sha256-8JzU0JVb+JQCNiro8hPHBwkofNTUy90YkSCzTOoB+/A=";
};
yarnOfflineCacheServer = fetchYarnDeps {
yarnLock = "${src}/yarn.lock";
-
hash = "sha256-pzXH6hdDf8O6Kr12Xw0jRcnPRD2TrDGdiEfxVr3KmwY=";
};
-
yarnOfflineCacheTools = fetchYarnDeps {
-
yarnLock = "${src}/server/tools/yarn.lock";
-
hash = "sha256-maPR8OCiuNlle0JQIkZSgAqW+BrSxPwVm6CkxIrIg5k=";
};
-
yarnOfflineCacheClient = fetchYarnDeps {
-
yarnLock = "${src}/client/yarn.lock";
-
hash = "sha256-Ejzk/VEx7YtJpsrkHcXAZnJ+yRx1VhBJGpqquHYULNU=";
};
-
nativeBuildInputs = [ brotli prefetch-yarn-deps jq nodejs which yarn ];
buildPhase = ''
# Build node modules
export HOME=$PWD
fixup-yarn-lock ~/yarn.lock
-
fixup-yarn-lock ~/server/tools/yarn.lock
fixup-yarn-lock ~/client/yarn.lock
yarn config --offline set yarn-offline-mirror $yarnOfflineCacheServer
-
yarn install --offline --frozen-lockfile --ignore-engines --ignore-scripts --no-progress
-
cd ~/server/tools
-
yarn config --offline set yarn-offline-mirror $yarnOfflineCacheTools
yarn install --offline --frozen-lockfile --ignore-engines --ignore-scripts --no-progress
cd ~/client
yarn config --offline set yarn-offline-mirror $yarnOfflineCacheClient
yarn install --offline --frozen-lockfile --ignore-engines --ignore-scripts --no-progress
-
patchShebangs ~/node_modules
-
patchShebangs ~/server/tools/node_modules
-
patchShebangs ~/client/node_modules
-
patchShebangs ~/scripts
# Fix bcrypt node module
cd ~/node_modules/bcrypt
···
cd ~
# Build PeerTube server
-
npm run tsc -- --build ./tsconfig.json
-
npm run resolve-tspaths:server
-
cp -r "./server/static" "./server/assets" "./dist/server"
-
cp -r "./server/lib/emails" "./dist/server/lib"
-
-
# Build PeerTube tools
-
cp -r "./server/tools/node_modules" "./dist/server/tools"
-
npm run tsc -- --build ./server/tools/tsconfig.json
-
npm run resolve-tspaths:server
# Build PeerTube client
npm run build:client
'';
installPhase = ''
mkdir -p $out/dist
mv ~/dist $out
mv ~/node_modules $out/node_modules
-
mv ~/server/tools/node_modules $out/dist/server/tools/node_modules
mkdir $out/client
mv ~/client/{dist,node_modules,package.json,yarn.lock} $out/client
-
mv ~/{config,scripts,support,CREDITS.md,FAQ.md,LICENSE,README.md,package.json,tsconfig.json,yarn.lock} $out
# Create static gzip and brotli files
find $out/client/dist -type f -regextype posix-extended -iregex '.*\.(css|eot|html|js|json|svg|webmanifest|xlf)' | while read file; do
···
x86_64-linux = {
arch = "linux-x64";
libc = "glibc";
+
hash = "sha256-C5N6VgFtXPLLjZt0ZdRTX095njRIT+12ONuUaBBj7fQ=";
};
aarch64-linux = {
arch = "linux-arm64";
libc = "glibc";
+
hash = "sha256-TerDujO+IkSRnHYlSbAKSP9IS7AT7XnQJsZ8D8pCoGc=";
};
x86_64-darwin = {
arch = "darwin-x64";
libc = "unknown";
+
hash = "sha256-gphOONWujbeCCr6dkmMRJP94Dhp1Jvp2yt+g7n1HTv0=";
};
aarch64-darwin = {
arch = "darwin-arm64";
libc = "unknown";
+
hash = "sha256-JMnELVUxoU1C57Tzue3Sg6OfDFAjfCnzgDit0BWzmlo=";
};
};
bcryptAttrs = bcryptHostPlatformAttrs."${stdenv.hostPlatform.system}" or
(throw "Unsupported architecture: ${stdenv.hostPlatform.system}");
+
bcryptVersion = "5.1.1";
bcryptLib = fetchurl {
url = "https://github.com/kelektiv/node.bcrypt.js/releases/download/v${bcryptVersion}/bcrypt_lib-v${bcryptVersion}-napi-v3-${bcryptAttrs.arch}-${bcryptAttrs.libc}.tar.gz";
inherit (bcryptAttrs) hash;
···
in
stdenv.mkDerivation rec {
pname = "peertube";
+
version = "6.0.3";
src = fetchFromGitHub {
owner = "Chocobozzz";
repo = "PeerTube";
rev = "v${version}";
+
hash = "sha256-Pskxfi+qqVk75hu22niLNFsToCJks1k8w8mTnXjr6jg=";
};
yarnOfflineCacheServer = fetchYarnDeps {
yarnLock = "${src}/yarn.lock";
+
hash = "sha256-RJX92EgEIXWB1wNFRl8FvseOqBT+7m6gs+pMyoodruk=";
+
};
+
+
yarnOfflineCacheClient = fetchYarnDeps {
+
yarnLock = "${src}/client/yarn.lock";
+
hash = "sha256-vr9xn5NXwiUS59Kgl8olCtkMgxnI1TKQzibKbb8RNXA=";
};
+
yarnOfflineCacheAppsCli = fetchYarnDeps {
+
yarnLock = "${src}/apps/peertube-cli/yarn.lock";
+
hash = "sha256-xsB71bnaPn/9/f1KHyU3TTwx+Q+1dLjWmNK2aVJgoRY=";
};
+
yarnOfflineCacheAppsRunner = fetchYarnDeps {
+
yarnLock = "${src}/apps/peertube-runner/yarn.lock";
+
hash = "sha256-9w3aLuiLs7SU00YwuE0ixfiD77gCakXT4YeRpfsgGz0=";
};
+
outputs = [ "out" "cli" "runner" ];
+
+
nativeBuildInputs = [ brotli prefetch-yarn-deps jq which yarn ];
+
+
buildInputs = [ nodejs ];
buildPhase = ''
# Build node modules
export HOME=$PWD
fixup-yarn-lock ~/yarn.lock
fixup-yarn-lock ~/client/yarn.lock
+
fixup-yarn-lock ~/apps/peertube-cli/yarn.lock
+
fixup-yarn-lock ~/apps/peertube-runner/yarn.lock
yarn config --offline set yarn-offline-mirror $yarnOfflineCacheServer
yarn install --offline --frozen-lockfile --ignore-engines --ignore-scripts --no-progress
cd ~/client
yarn config --offline set yarn-offline-mirror $yarnOfflineCacheClient
+
yarn install --offline --frozen-lockfile --ignore-engines --ignore-scripts --no-progress
+
cd ~/apps/peertube-cli
+
yarn config --offline set yarn-offline-mirror $yarnOfflineCacheAppsCli
+
yarn install --offline --frozen-lockfile --ignore-engines --ignore-scripts --no-progress
+
cd ~/apps/peertube-runner
+
yarn config --offline set yarn-offline-mirror $yarnOfflineCacheAppsRunner
yarn install --offline --frozen-lockfile --ignore-engines --ignore-scripts --no-progress
+
patchShebangs ~/{node_modules,client/node_modules,/apps/peertube-cli/node_modules,apps/peertube-runner/node_modules,scripts}
# Fix bcrypt node module
cd ~/node_modules/bcrypt
···
cd ~
# Build PeerTube server
+
npm run build:server
# Build PeerTube client
npm run build:client
+
+
# Build PeerTube cli
+
npm run build:peertube-cli
+
patchShebangs ~/apps/peertube-cli/dist/peertube.js
+
+
# Build PeerTube runner
+
npm run build:peertube-runner
+
patchShebangs ~/apps/peertube-runner/dist/peertube-runner.js
+
+
# Clean up declaration files
+
find ~/dist/ \
+
~/packages/core-utils/dist/ \
+
~/packages/ffmpeg/dist/ \
+
~/packages/models/dist/ \
+
~/packages/node-utils/dist/ \
+
~/packages/server-commands/dist/ \
+
~/packages/typescript-utils/dist/ \
+
\( -name '*.d.ts' -o -name '*.d.ts.map' \) -type f -delete
'';
installPhase = ''
mkdir -p $out/dist
mv ~/dist $out
mv ~/node_modules $out/node_modules
mkdir $out/client
mv ~/client/{dist,node_modules,package.json,yarn.lock} $out/client
+
mkdir -p $out/packages/{core-utils,ffmpeg,models,node-utils,server-commands,typescript-utils}
+
mv ~/packages/core-utils/{dist,package.json} $out/packages/core-utils
+
mv ~/packages/ffmpeg/{dist,package.json} $out/packages/ffmpeg
+
mv ~/packages/models/{dist,package.json} $out/packages/models
+
mv ~/packages/node-utils/{dist,package.json} $out/packages/node-utils
+
mv ~/packages/server-commands/{dist,package.json} $out/packages/server-commands
+
mv ~/packages/typescript-utils/{dist,package.json} $out/packages/typescript-utils
+
mv ~/{config,support,CREDITS.md,FAQ.md,LICENSE,README.md,package.json,yarn.lock} $out
+
+
mkdir -p $cli/bin
+
mv ~/apps/peertube-cli/{dist,node_modules,package.json,yarn.lock} $cli
+
ln -s $cli/dist/peertube.js $cli/bin/peertube-cli
+
+
mkdir -p $runner/bin
+
mv ~/apps/peertube-runner/{dist,node_modules,package.json,yarn.lock} $runner
+
ln -s $runner/dist/peertube-runner.js $runner/bin/peertube-runner
# Create static gzip and brotli files
find $out/client/dist -type f -regextype posix-extended -iregex '.*\.(css|eot|html|js|json|svg|webmanifest|xlf)' | while read file; do