feat(capytal,peertube): capytal's peertube instance

This commit is contained in:
Guz
2025-11-30 20:39:31 -03:00
parent 470d719f80
commit 9ad046f2be
5 changed files with 191 additions and 7 deletions

View File

@@ -1,5 +1,7 @@
{...}: { {...}: {
imports = [ imports = [
# ./admin.nix
./peertube.nix
./analytics.nix ./analytics.nix
./forge.nix ./forge.nix
./websites.nix ./websites.nix

162
capytal/videos.nix Normal file
View File

@@ -0,0 +1,162 @@
{
config,
lib,
pkgs,
...
}: let
cfg = config.services.peertube;
systemCallsList = [
"@cpu-emulation"
"@debug"
"@keyring"
"@ipc"
"@memlock"
"@mount"
"@obsolete"
"@privileged"
"@setuid"
];
cfgService = {
# Proc filesystem
ProtectProc = "invisible";
# Access write directories
UMask = "0027";
# Capabilities
CapabilityBoundingSet = "";
# Security
NoNewPrivileges = true;
# Sandboxing
ProtectSystem = "strict";
ProtectHome = true;
PrivateTmp = true;
PrivateDevices = true;
PrivateUsers = true;
ProtectClock = true;
ProtectHostname = true;
ProtectKernelLogs = true;
ProtectKernelModules = true;
ProtectKernelTunables = true;
ProtectControlGroups = true;
RestrictNamespaces = true;
LockPersonality = true;
RestrictRealtime = true;
RestrictSUIDSGID = true;
RemoveIPC = true;
PrivateMounts = true;
# System Call Filtering
SystemCallArchitectures = "native";
};
in {
services.peertube = {
enable = true;
# localDomain = "watch.capytal.cc";
localDomain = "watch-test.capytal.cc";
listenWeb = 9945;
listenHttp = 9945;
enableWebHttps = false;
database = {
# createLocally = true;
host = "/run/postgresql";
port = config.services.postgresql.settings.port;
passwordFile = config.sops.secrets."peertube/database/password".path;
};
redis.createLocally = true;
configureNginx = true;
settings = {
signup.enabled = false;
object_storage = {
enabled = true;
endpoint = "localhost:3461";
region = "garage";
videos = {
bucket_name = "peertube";
prefix = "hls-videos:";
};
streaming_playlists = {
bucket_name = "peertube";
prefix = "streaming-playlists:";
};
user_exports = {
bucket_name = "peertube";
prefix = "user-exports:";
};
original_video_files = {
bucket_name = "peertube";
prefix = "original-video-files:";
};
captions = {
bucket_name = "peertube";
prefix = "captions:";
};
};
webserver = {
hostname = cfg.localDomain;
port = lib.mkForce 443;
};
};
secrets.secretsFile = config.sops.secrets."peertube/secretsFile".path;
serviceEnvironmentFile = config.sops.secrets."peertube/environment".path;
# TODO: Set up postfix server for forms and contact
};
# TODO: Commit this to upstream nixpkgs?
# HACK: services.peertube.database.createLocally option doesn't respect port
systemd.services.peertube-init-db = {
description = "Initialization database for PeerTube daemon";
after = [
"network.target"
"postgresql.service"
];
requires = ["postgresql.service"];
script = let
psqlSetupCommands = pkgs.writeText "peertube-init.sql" ''
SELECT 'CREATE USER "${cfg.database.user}"' WHERE NOT EXISTS (SELECT FROM pg_roles WHERE rolname = '${cfg.database.user}')\gexec
SELECT 'CREATE DATABASE "${cfg.database.name}" OWNER "${cfg.database.user}" TEMPLATE template0 ENCODING UTF8' WHERE NOT EXISTS (SELECT FROM pg_database WHERE datname = '${cfg.database.name}')\gexec
\c '${cfg.database.name}'
CREATE EXTENSION IF NOT EXISTS pg_trgm;
CREATE EXTENSION IF NOT EXISTS unaccent;
'';
in "${config.services.postgresql.package}/bin/psql -f ${psqlSetupCommands} -p ${toString config.services.postgresql.settings.port}";
serviceConfig =
{
Type = "oneshot";
WorkingDirectory = cfg.package;
# User and group
User = "postgres";
Group = "postgres";
# Sandboxing
RestrictAddressFamilies = ["AF_UNIX"];
MemoryDenyWriteExecute = true;
# System Call Filtering
SystemCallFilter = "~" + lib.concatStringsSep " " (systemCallsList ++ ["@resources"]);
}
// cfgService;
};
services.anubis.instances."peertube" = {
settings = {
BIND = ":${toString (cfg.listenWeb + 2)}";
BIND_NETWORK = "tcp";
METRICS_BIND = ":${toString (cfg.listenWeb + 3)}";
METRICS_BIND_NETWORK = "tcp";
SERVE_ROBOTS_TXT = true;
TARGET = "http://localhost:${toString cfg.listenWeb}";
ED25519_PRIVATE_KEY_HEX_FILE = config.sops.secrets."anubis/peertube/hex_file".path;
};
};
services.caddy.virtualHosts = {
":${toString (cfg.listenWeb + 1)}" = {
extraConfig = ''
reverse_proxy http://localhost${config.services.anubis.instances."peertube".settings.BIND} {
header_up X-Http-Version {http.request.proto}
header_up X-Real-Ip {remote_host}
}
'';
};
};
}

View File

@@ -1,22 +1,21 @@
{ {
config, config,
lib, lib,
pkgs,
... ...
}: let }: let
cfg = config.services.postgresql; cfg = config.services.postgresql;
cfgadm = config.services.pgadmin;
in { in {
services.postgresql = { services.postgresql = {
enable = true;
enableTCPIP = true;
authentication = lib.mkForce '' authentication = lib.mkForce ''
#type database DBuser origin-address auth-method #type database DBuser origin-address auth-method
local all all trust local all all trust
# ipv4 # ipv4
host all all 172.0.0.1/32 trust host all all 127.0.0.1/32 trust
# ipv6 # ipv6
host all all ::1/128 trust host all all ::1/128 trust
''; '';
enable = true;
ensureDatabases = [ ensureDatabases = [
"forgejo" "forgejo"
"nextcloud" "nextcloud"
@@ -31,7 +30,6 @@ in {
ensureDBOwnership = true; ensureDBOwnership = true;
} }
]; ];
enableTCPIP = true;
settings = { settings = {
port = 3245; port = 3245;
}; };

View File

@@ -33,6 +33,7 @@ with lib; {
# Anubis # Anubis
${config.services.anubis.defaultOptions.user} = [ ${config.services.anubis.defaultOptions.user} = [
"anubis/gitea/hex_file" "anubis/gitea/hex_file"
"anubis/peertube/hex_file"
"anubis/medama/hex_file" "anubis/medama/hex_file"
]; ];
@@ -61,6 +62,18 @@ with lib; {
"keiko/env_file" "keiko/env_file"
]; ];
# Peertube
${config.services.peertube.user} = [
"peertube/database/password"
"peertube/environment"
"peertube/secretsFile"
];
# PostgreSQL
${config.users.users.postgres.name} = [
"postgresql/initialScript"
];
# Nextcloud # Nextcloud
${config.services.phpfpm.pools.nextcloud.user} = [ ${config.services.phpfpm.pools.nextcloud.user} = [
"nextcloud/adminpass" "nextcloud/adminpass"

View File

@@ -3,6 +3,8 @@ anubis:
hex_file: ENC[AES256_GCM,data:UlFkdy1MfwaQqDnxtMtg4kH/dMJVl8sk4DMfdaCczHGaPtPuP4ADxcBxqpNkzYnQPxbv5ZXqR4qz8Ur5QHWxUg==,iv:WQHkSMiJEV0IWMVvfxC/EuE/e8QabhJinRHADm7kdSg=,tag:1JRwMp94APRszgBuQ0yaQQ==,type:str] hex_file: ENC[AES256_GCM,data:UlFkdy1MfwaQqDnxtMtg4kH/dMJVl8sk4DMfdaCczHGaPtPuP4ADxcBxqpNkzYnQPxbv5ZXqR4qz8Ur5QHWxUg==,iv:WQHkSMiJEV0IWMVvfxC/EuE/e8QabhJinRHADm7kdSg=,tag:1JRwMp94APRszgBuQ0yaQQ==,type:str]
gitea: gitea:
hex_file: ENC[AES256_GCM,data:VeF2FRqZdsYe3A002QLGG8jc5s+Tfr5V4dpO/aZ4Rbh9T/O3XQznocDsmUOvjIysH9wbVwvBXGdH1U3vd0qmVg==,iv:/3VQLK+C76HoCbpZAUQaxOFsiFKDuuP2KWAV0EBasp4=,tag:brqDAaHv7r9DRLBoMMmRqw==,type:str] hex_file: ENC[AES256_GCM,data:VeF2FRqZdsYe3A002QLGG8jc5s+Tfr5V4dpO/aZ4Rbh9T/O3XQznocDsmUOvjIysH9wbVwvBXGdH1U3vd0qmVg==,iv:/3VQLK+C76HoCbpZAUQaxOFsiFKDuuP2KWAV0EBasp4=,tag:brqDAaHv7r9DRLBoMMmRqw==,type:str]
peertube:
hex_file: ENC[AES256_GCM,data:1G2MZRpGFVr2Pd2eRlaLyVfYY+DrCtqfaBaC3S/dVrDJr8s7Xw7w622ILNUflZAEcYKCvpI25oNNnCG0pw6L3g==,iv:1VHhQ5Y2gdZeZIadWy2YyCYA8k79Acm0sE4MjWZYChg=,tag:G3u80vSy3hTYcsGCy9HZrg==,type:str]
medama: medama:
hex_file: ENC[AES256_GCM,data:wLRw34+uPWpR5GJuI8Q+nlX4hEx3sMn5mSl/lF5kX0Z8N99Eb6Qj4Emx2mK4dNukYNO8j9blw1/RAL94I+QCjQ==,iv:/dW5Z+S14dByXIUyOyEIxxRFl7e4lZZfBKtukV4s68M=,tag:fELbLVzwIgMJUjhNJw4kYg==,type:str] hex_file: ENC[AES256_GCM,data:wLRw34+uPWpR5GJuI8Q+nlX4hEx3sMn5mSl/lF5kX0Z8N99Eb6Qj4Emx2mK4dNukYNO8j9blw1/RAL94I+QCjQ==,iv:/dW5Z+S14dByXIUyOyEIxxRFl7e4lZZfBKtukV4s68M=,tag:fELbLVzwIgMJUjhNJw4kYg==,type:str]
cloudflared: cloudflared:
@@ -41,6 +43,13 @@ guz:
password: ENC[AES256_GCM,data:zlO5xSFho7TXjFv62lgFir9SAgn+UE6XjdNEvIAgmQG9oDkthfgxO84wYdI0mQDwRIIs2PmSdBRfo0DPc3hji+ySCrItolPL8g==,iv:MZfhTxwfcbmXh5C6DkQhnY9NQGdE8zEwwvFOHQiUgKY=,tag:JjJN2bYcSXNN3ueGj5RNLg==,type:str] password: ENC[AES256_GCM,data:zlO5xSFho7TXjFv62lgFir9SAgn+UE6XjdNEvIAgmQG9oDkthfgxO84wYdI0mQDwRIIs2PmSdBRfo0DPc3hji+ySCrItolPL8g==,iv:MZfhTxwfcbmXh5C6DkQhnY9NQGdE8zEwwvFOHQiUgKY=,tag:JjJN2bYcSXNN3ueGj5RNLg==,type:str]
keiko: keiko:
env_file: ENC[AES256_GCM,data:dgHWczdwDxz3yV66F+4lMTRIMvHDBYZ6ycVARQPVT7GcYhelA/5uNks3Sdn1n8vgie7TmZBT9mGv+ePtP4+GMyHo/bOJqvjcXyU9dB30CwxuYOCPefitbKxHwIJxkMJqmXvNr3pl2u0mZWUu3mdGMLI9fF3z8/Tk0xM/g4ZezLGaXcRhUSdQPDiOFt2VKA5IrERnpRP0ey5Jx3tf,iv:gpLQdIBGgMCgR0B7jEZDF+3t85nsOVkdxubBUR+QOWA=,tag:eTgQ2uvWsGPEXkpzj/3Szw==,type:str] env_file: ENC[AES256_GCM,data:dgHWczdwDxz3yV66F+4lMTRIMvHDBYZ6ycVARQPVT7GcYhelA/5uNks3Sdn1n8vgie7TmZBT9mGv+ePtP4+GMyHo/bOJqvjcXyU9dB30CwxuYOCPefitbKxHwIJxkMJqmXvNr3pl2u0mZWUu3mdGMLI9fF3z8/Tk0xM/g4ZezLGaXcRhUSdQPDiOFt2VKA5IrERnpRP0ey5Jx3tf,iv:gpLQdIBGgMCgR0B7jEZDF+3t85nsOVkdxubBUR+QOWA=,tag:eTgQ2uvWsGPEXkpzj/3Szw==,type:str]
postgresql:
initialScript: ENC[AES256_GCM,data:9ByABGVJgE7+CpWTiRLvN8PM2N4UjRylcFR7zjSeROkpkJQfxaJas0G2kLo9wRXVbp82NlIb8A5kd7pFCfF/GC7G7bqfIiR65yevLJ+SScEnhx2YSd5U1dTNwgaK48Q2b9aACn5qOVCwA0WgKkUZMBH2G6u/9VCHjFWXnoVX1YqQ1IwiCE4aSwGdiSykMQXldLnVDB/CDhir7x6/M+jroW+hrkrmXVXZbM5JRTz4foUEafhjFInZXbPKJl+rgNv//DAG4tYWCOljruRVmtKo9CJm277/8C2jd5NwVUFsBmDuvIQjrSBo25r7UMV+US7JJO2gjw/81QraNy95nTxdIAphTqV4W1eeZIxWwDKul6WvyNwTsa/Zw8nUHmlf1i7NWiy+YaqJHrPWXPnytTNLuFsm34sU5Jair4l4LRkzUW/+wZk3977xbmVbUwimywO7,iv:rOP9dSSnWiJKe30hxD4+klj/JZygcEsskf+71zn5Eu4=,tag:nz11prtg2DiK+EODarIYFA==,type:str]
peertube:
database:
password: ENC[AES256_GCM,data:PUHAXOXMwDVFc7cHihhizQ==,iv:FgUKffolNJrK/hqTnm0ciYdQDl6VjCXeEp+tyfa+Wmo=,tag:Mcxjlcd4Hr+x91Cx4/9p7w==,type:str]
secretsFile: ENC[AES256_GCM,data:3ZlvLnxollbqo7tLKbq81cGcYkbVqhmRe/3h0XOyPDgXtOvaiVKkUeIbbTmhdai4ueQcEF5U7xn0Lc8FZqLE2Q==,iv:H2quDSKPaVNLq91nqHxVvOh/611Ej2prAf1Rd3/8AOQ=,tag:CGqTSJNqiaFoFR21PabwRA==,type:str]
environment: ENC[AES256_GCM,data:z4C957prGW1EoDnnjO1DiW6d4qlIkBwAdE/wXDVSvgwWczz2u6YgDPA+QuIC2OkfcSzlz5kslCoBLtVubiQRnjgUJhXAFXfilD0+cLq82Kak9LAZAkuGyhivTGmNg0rpOh9qamns5hpXXlbu8/VFyCX/XWv6gN0P3GeS+As7QNhm7M9O,iv:qb5kAhljVF45+bluZ6t3kNHZ2+C3g/8pnDjVe+1v6bs=,tag:GYmtgfcyCTxHNpq4rHSXvg==,type:str]
nextcloud: nextcloud:
adminpass: ENC[AES256_GCM,data:RY2BsFDSttpr,iv:Mv22/Ht4Uq0miQjKgbnu37UCk/wZMyc6t9jrWkyXsxI=,tag:ScYTA46R0ZpkeqjhRsYzYg==,type:str] adminpass: ENC[AES256_GCM,data:RY2BsFDSttpr,iv:Mv22/Ht4Uq0miQjKgbnu37UCk/wZMyc6t9jrWkyXsxI=,tag:ScYTA46R0ZpkeqjhRsYzYg==,type:str]
s3: s3:
@@ -57,7 +66,7 @@ sops:
amRmVkVoS2RqeEs3OXZVeTlsZUVEV28K1WcbGJHT8LMah5b7NN1psiucTl1OfZYO amRmVkVoS2RqeEs3OXZVeTlsZUVEV28K1WcbGJHT8LMah5b7NN1psiucTl1OfZYO
4T3RDSQMB3qj1TGQSdixjwRRKbMGtL3LXnvkNd+caVi5Z9OkF1O9Yg== 4T3RDSQMB3qj1TGQSdixjwRRKbMGtL3LXnvkNd+caVi5Z9OkF1O9Yg==
-----END AGE ENCRYPTED FILE----- -----END AGE ENCRYPTED FILE-----
lastmodified: "2025-10-10T21:47:17Z" lastmodified: "2025-11-30T16:31:04Z"
mac: ENC[AES256_GCM,data:4K5fNM05Mm3VCFTx2lntPUcaW/fznjchMdd26VJURBTED3Hr8wpLyNMFtWqWlKZvVuMyk7VQyyBmysb0clmydHpuDR9TtJSJA+IyIyK6IQJi86mQs7IpcSf4Z6uXA33ed3z2aJWhwA8l+5XtwQjYQbDeME1v/ir7xTeqz8P4STI=,iv:iaXcW+3UumdAR/v4/Pp8ZCqJQ2WmL6fucRFJwTugxrc=,tag:sxUajgkMkYjshIgU24o+/w==,type:str] mac: ENC[AES256_GCM,data:74FbU0xXoMhVt+gYFnl3T3GeWdAzXTR7f3SZztTRwtgyEIX/ktvZsKXaAUstTbz5zjybBr5zlwwXKSIL2bM3R5oSva7LVNTkbLBPSad8/O8iQtq8BSKVVHFhvjBfAbpVmZVlUgNzUCS2X+bZwHO3Tl0KgEYozXPQa66jwTUVF0w=,iv:XebXM0AP+53qxWJMKSjqVJsdwWXwglcGmx1mqKgzcf8=,tag:yniIwNDOrSY7KFYDggb+/g==,type:str]
unencrypted_suffix: _unencrypted unencrypted_suffix: _unencrypted
version: 3.10.2 version: 3.10.2