feat(capytal,peertube): capytal's peertube instance
This commit is contained in:
@@ -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
162
capytal/videos.nix
Normal 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}
|
||||||
|
}
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
};
|
||||||
|
}
|
||||||
@@ -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;
|
||||||
};
|
};
|
||||||
|
|||||||
13
secrets.nix
13
secrets.nix
@@ -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"
|
||||||
|
|||||||
13
secrets.yaml
13
secrets.yaml
@@ -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
|
||||||
|
|||||||
Reference in New Issue
Block a user