nginx & jellyfin modularized
This commit is contained in:
parent
e5e55cd406
commit
a24ed21f39
1
base.nix
1
base.nix
@ -5,6 +5,7 @@
|
|||||||
./modules/dev.nix
|
./modules/dev.nix
|
||||||
./modules/shell.nix
|
./modules/shell.nix
|
||||||
./modules/services.nix
|
./modules/services.nix
|
||||||
|
./modules/servers.nix
|
||||||
./modules/scripts.nix
|
./modules/scripts.nix
|
||||||
./jawz.nix
|
./jawz.nix
|
||||||
];
|
];
|
||||||
|
|||||||
@ -92,12 +92,7 @@
|
|||||||
];
|
];
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
environment.systemPackages = with pkgs; [
|
environment.systemPackages = with pkgs; [ wget ];
|
||||||
wget
|
|
||||||
jellyfin-ffmpeg # coolest video converter!
|
|
||||||
mediainfo # nextcloud
|
|
||||||
dlib
|
|
||||||
];
|
|
||||||
services = {
|
services = {
|
||||||
btrfs.autoScrub.fileSystems = [ "/mnt/pool" ];
|
btrfs.autoScrub.fileSystems = [ "/mnt/pool" ];
|
||||||
# minidlna = {
|
# minidlna = {
|
||||||
|
|||||||
@ -7,8 +7,6 @@
|
|||||||
docker = {
|
docker = {
|
||||||
enable = true;
|
enable = true;
|
||||||
enableNvidia = true;
|
enableNvidia = true;
|
||||||
# dockerCompat = true;
|
|
||||||
# defaultNetwork.settings.dns_enabled = true;
|
|
||||||
autoPrune = {
|
autoPrune = {
|
||||||
enable = true;
|
enable = true;
|
||||||
flags = [ "--all" ];
|
flags = [ "--all" ];
|
||||||
@ -16,31 +14,7 @@
|
|||||||
};
|
};
|
||||||
};
|
};
|
||||||
oci-containers = {
|
oci-containers = {
|
||||||
backend = "docker";
|
|
||||||
containers = {
|
containers = {
|
||||||
collabora = {
|
|
||||||
autoStart = true;
|
|
||||||
image = "collabora/code";
|
|
||||||
imageFile = pkgs.dockerTools.pullImage {
|
|
||||||
imageName = "collabora/code";
|
|
||||||
imageDigest =
|
|
||||||
"sha256:aab41379baf5652832e9237fcc06a768096a5a7fccc66cf8bd4fdb06d2cbba7f";
|
|
||||||
sha256 = "sha256-M66lynhzaOEFnE15Sy1N6lBbGDxwNw6ap+IUJAvoCLs=";
|
|
||||||
};
|
|
||||||
ports = [ "9980:9980" ];
|
|
||||||
environment = {
|
|
||||||
TZ = "America/Mexico_City";
|
|
||||||
domain = "cloud.servidos.lat";
|
|
||||||
aliasgroup1 = "cloud.servidos.lat:443";
|
|
||||||
aliasgroup2 = "cloud.rotehaare.art:443";
|
|
||||||
dictionaries = "en_CA en_US es_MX es_ES fr_FR it pt_BR ru";
|
|
||||||
extra_params = ''
|
|
||||||
--o:ssl.enable=false
|
|
||||||
--o:ssl.termination=true
|
|
||||||
'';
|
|
||||||
};
|
|
||||||
extraOptions = [ "--cap-add" "MKNOD" ];
|
|
||||||
};
|
|
||||||
# metube = {
|
# metube = {
|
||||||
# image = "ghcr.io/alexta69/metube";
|
# image = "ghcr.io/alexta69/metube";
|
||||||
# ports = [ "8881:8081" ];
|
# ports = [ "8881:8081" ];
|
||||||
@ -209,19 +183,6 @@
|
|||||||
"flame.icon" = "fridge";
|
"flame.icon" = "fridge";
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
go-vod = {
|
|
||||||
autoStart = true;
|
|
||||||
image = "radialapps/go-vod";
|
|
||||||
environment = {
|
|
||||||
TZ = "America/Mexico_City";
|
|
||||||
NEXTCLOUD_HOST = "https://${config.services.nextcloud.hostName}";
|
|
||||||
NVIDIA_VISIBLE_DEVICES = "all";
|
|
||||||
};
|
|
||||||
volumes = [ "ncdata:/var/www/html:ro" ];
|
|
||||||
extraOptions = [
|
|
||||||
"--device=/dev/dri" # VA-API (omit for NVENC)
|
|
||||||
];
|
|
||||||
};
|
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|||||||
@ -7,10 +7,7 @@ let
|
|||||||
localhost = "127.0.0.1";
|
localhost = "127.0.0.1";
|
||||||
# workstation = "192.168.1.64";
|
# workstation = "192.168.1.64";
|
||||||
domain = "servidos.lat";
|
domain = "servidos.lat";
|
||||||
jellyfinPort = 8096;
|
|
||||||
shioriPort = 4368;
|
shioriPort = 4368;
|
||||||
# nextcloudPort = 80;
|
|
||||||
collaboraPort = 9980;
|
|
||||||
flamePort = 5005;
|
flamePort = 5005;
|
||||||
secretFlamePort = 5007;
|
secretFlamePort = 5007;
|
||||||
# lidarrPort = 8686;
|
# lidarrPort = 8686;
|
||||||
@ -37,13 +34,6 @@ in {
|
|||||||
# recommendedGzipSettings = true;
|
# recommendedGzipSettings = true;
|
||||||
# recommendedOptimisation = true;
|
# recommendedOptimisation = true;
|
||||||
sslCiphers = "AES256+EECDH:AES256+EDH:!aNULL";
|
sslCiphers = "AES256+EECDH:AES256+EDH:!aNULL";
|
||||||
appendHttpConfig = ''
|
|
||||||
# JELLYFIN
|
|
||||||
proxy_cache_path /var/cache/nginx/jellyfin-videos levels=1:2 keys_zone=jellyfin-videos:100m inactive=90d max_size=35000m;
|
|
||||||
proxy_cache_path /var/cache/nginx/jellyfin levels=1:2 keys_zone=jellyfin:100m max_size=15g inactive=30d use_temp_path=off;
|
|
||||||
map $request_uri $h264Level { ~(h264-level=)(.+?)& $2; }
|
|
||||||
map $request_uri $h264Profile { ~(h264-profile=)(.+?)& $2; }
|
|
||||||
'';
|
|
||||||
virtualHosts = let
|
virtualHosts = let
|
||||||
base = locations: {
|
base = locations: {
|
||||||
inherit locations;
|
inherit locations;
|
||||||
@ -125,128 +115,7 @@ in {
|
|||||||
'';
|
'';
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
"flix.${domain}" = {
|
|
||||||
forceSSL = true;
|
|
||||||
enableACME = true;
|
|
||||||
http2 = true;
|
|
||||||
extraConfig = ''
|
|
||||||
# use a variable to store the upstream proxy
|
|
||||||
# in this example we are using a hostname which is resolved via DNS
|
|
||||||
# (if you aren't using DNS remove the resolver line and change the variable to point to an IP address
|
|
||||||
resolver ${localhost} valid=30;
|
|
||||||
|
|
||||||
location = / {
|
|
||||||
return 302 http://$host/web/;
|
|
||||||
#return 302 https://$host/web/;
|
|
||||||
}
|
|
||||||
|
|
||||||
location = /web/ {
|
|
||||||
# Proxy main Jellyfin traffic
|
|
||||||
proxy_pass http://${localhost}:${
|
|
||||||
toString jellyfinPort
|
|
||||||
}/web/index.html;
|
|
||||||
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_set_header X-Forwarded-Proto $scheme;
|
|
||||||
proxy_set_header X-Forwarded-Protocol $scheme;
|
|
||||||
proxy_set_header X-Forwarded-Host $http_host;
|
|
||||||
}
|
|
||||||
'';
|
|
||||||
locations = {
|
|
||||||
"/" = {
|
|
||||||
proxyPass = "http://${localhost}:${toString jellyfinPort}";
|
|
||||||
proxyWebsockets = true;
|
|
||||||
};
|
|
||||||
"/socket" = {
|
|
||||||
proxyPass = "http://${localhost}:${toString jellyfinPort}";
|
|
||||||
extraConfig = ''
|
|
||||||
proxy_http_version 1.1;
|
|
||||||
proxy_set_header Upgrade $http_upgrade;
|
|
||||||
proxy_set_header Connection "upgrade";
|
|
||||||
'';
|
|
||||||
};
|
|
||||||
"~ /Items/(.*)/Images" = {
|
|
||||||
proxyPass = "http://${localhost}:${toString jellyfinPort}";
|
|
||||||
extraConfig = ''
|
|
||||||
proxy_cache jellyfin;
|
|
||||||
proxy_cache_revalidate on;
|
|
||||||
proxy_cache_lock on;
|
|
||||||
'';
|
|
||||||
};
|
|
||||||
"~* ^/Videos/(.*)/(?!live)" = {
|
|
||||||
proxyPass = "http://${localhost}:${toString jellyfinPort}";
|
|
||||||
extraConfig = ''
|
|
||||||
# Set size of a slice (this amount will be always requested from the backend by nginx)
|
|
||||||
# Higher value means more latency, lower more overhead
|
|
||||||
# This size is independent of the size clients/browsers can request
|
|
||||||
# slice 2m;
|
|
||||||
|
|
||||||
proxy_cache jellyfin-videos;
|
|
||||||
proxy_cache_valid 200 206 301 302 30d;
|
|
||||||
proxy_ignore_headers Expires Cache-Control Set-Cookie X-Accel-Expires;
|
|
||||||
proxy_cache_use_stale error timeout invalid_header updating http_500 http_502 http_503 http_504;
|
|
||||||
proxy_connect_timeout 15s;
|
|
||||||
proxy_http_version 1.1;
|
|
||||||
proxy_set_header Connection "";
|
|
||||||
# Transmit slice range to the backend
|
|
||||||
proxy_set_header Range 2m;
|
|
||||||
|
|
||||||
# This saves bandwidth between the proxy and jellyfin, as a file is only downloaded one time instead of multiple times when multiple clients want to at the same time
|
|
||||||
# The first client will trigger the download, the other clients will have to wait until the slice is cached
|
|
||||||
# Esp. practical during SyncPlay
|
|
||||||
proxy_cache_lock on;
|
|
||||||
proxy_cache_lock_age 60s;
|
|
||||||
|
|
||||||
proxy_cache_key "jellyvideo$uri?MediaSourceId=$arg_MediaSourceId&VideoCodec=$arg_VideoCodec&AudioCodec=$arg_AudioCodec&AudioStreamIndex=$arg_AudioStreamIndex&VideoBitrate=$arg_VideoBitrate&AudioBitrate=$arg_AudioBitrate&SubtitleMethod=$arg_SubtitleMethod&TranscodingMaxAudioChannels=$arg_TranscodingMaxAudioChannels&RequireAvc=$arg_RequireAvc&SegmentContainer=$arg_SegmentContainer&MinSegments=$arg_MinSegments&BreakOnNonKeyFrames=$arg_BreakOnNonKeyFrames&h264-profile=$h264Profile&h264-level=$h264Level&slicerange=2m";
|
|
||||||
|
|
||||||
# add_header X-Cache-Status $upstream_cache_status; # This is only for debugging cache
|
|
||||||
'';
|
|
||||||
};
|
|
||||||
};
|
|
||||||
};
|
|
||||||
${config.services.nextcloud.hostName} = {
|
|
||||||
forceSSL = true;
|
|
||||||
enableACME = true;
|
|
||||||
http2 = true;
|
|
||||||
serverAliases = [ "cloud.rotehaare.art" ];
|
|
||||||
locations = {
|
|
||||||
"/".proxyWebsockets = true;
|
|
||||||
# uh, equals what?
|
|
||||||
"~ ^/nextcloud/(?:index|remote|public|cron|core/ajax/update|status|ocs/v[12]|updater/.+|oc[ms]-provider/.+|.+/richdocumentscode/proxy).php(?:$|/)" =
|
|
||||||
{ };
|
|
||||||
};
|
|
||||||
};
|
|
||||||
|
|
||||||
"collabora.${domain}" = let
|
|
||||||
collaboraString = "http://${localhost}:${toString collaboraPort}";
|
|
||||||
collaboraProxy = {
|
|
||||||
proxyPass = collaboraString;
|
|
||||||
extraConfig = ''
|
|
||||||
proxy_set_header Host $host;
|
|
||||||
'';
|
|
||||||
};
|
|
||||||
collaboraSocket = {
|
|
||||||
proxyPass = collaboraString;
|
|
||||||
extraConfig = ''
|
|
||||||
proxy_set_header Upgrade $http_upgrade;
|
|
||||||
proxy_set_header Connection "Upgrade";
|
|
||||||
proxy_set_header Host $host;
|
|
||||||
proxy_read_timeout 36000s;
|
|
||||||
'';
|
|
||||||
};
|
|
||||||
in base {
|
|
||||||
# static files
|
|
||||||
"^~ /loleaflet" = collaboraProxy;
|
|
||||||
# WOPI discovery URL
|
|
||||||
"^~ /hosting/discovery" = collaboraProxy;
|
|
||||||
# Capabilities
|
|
||||||
"^~ /hosting/capabilities" = collaboraProxy;
|
|
||||||
# download, presentation, image upload and websocket
|
|
||||||
"~ ^/lool" = collaboraSocket;
|
|
||||||
# Admin Console websocket
|
|
||||||
"^~ /lool/adminws" = collaboraSocket;
|
|
||||||
};
|
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
networking = {
|
networking = {
|
||||||
|
|||||||
@ -39,7 +39,6 @@ in {
|
|||||||
"$@"
|
"$@"
|
||||||
'')
|
'')
|
||||||
];
|
];
|
||||||
users.groups = { piracy.gid = 985; };
|
|
||||||
users.users = let base = { isSystemUser = true; };
|
users.users = let base = { isSystemUser = true; };
|
||||||
in {
|
in {
|
||||||
# # prowlarr = base // { group = "piracy"; };
|
# # prowlarr = base // { group = "piracy"; };
|
||||||
@ -47,36 +46,6 @@ in {
|
|||||||
# # group = "kavita";
|
# # group = "kavita";
|
||||||
# # extraGroups = [ "piracy" ];
|
# # extraGroups = [ "piracy" ];
|
||||||
# # };
|
# # };
|
||||||
nextcloud = base // {
|
|
||||||
extraGroups = [ "render" ];
|
|
||||||
packages = (with pkgs; [
|
|
||||||
nodejs
|
|
||||||
(python3.withPackages (ps: with ps; [ tensorflow ]))
|
|
||||||
perl
|
|
||||||
(perlPackages.buildPerlPackage rec {
|
|
||||||
pname = "Image-ExifTool";
|
|
||||||
version = "12.70";
|
|
||||||
src = fetchurl {
|
|
||||||
url = "https://exiftool.org/Image-ExifTool-${version}.tar.gz";
|
|
||||||
hash = "sha256-TLJSJEXMPj870TkExq6uraX8Wl4kmNerrSlX3LQsr/4=";
|
|
||||||
};
|
|
||||||
})
|
|
||||||
]);
|
|
||||||
};
|
|
||||||
};
|
|
||||||
programs = {
|
|
||||||
msmtp = {
|
|
||||||
enable = true;
|
|
||||||
accounts.default = {
|
|
||||||
auth = true;
|
|
||||||
host = "smtp.gmail.com";
|
|
||||||
port = 587;
|
|
||||||
tls = true;
|
|
||||||
from = "stunner6399@gmail.com";
|
|
||||||
user = "stunner6399@gmail.com";
|
|
||||||
password = "eqyctcgjdykqeuwt";
|
|
||||||
};
|
|
||||||
};
|
|
||||||
};
|
};
|
||||||
services = let
|
services = let
|
||||||
base = {
|
base = {
|
||||||
@ -87,7 +56,6 @@ in {
|
|||||||
# sonarr = base // { package = pkgs.sonarr; };
|
# sonarr = base // { package = pkgs.sonarr; };
|
||||||
# radarr = base // { package = pkgs.radarr; };
|
# radarr = base // { package = pkgs.radarr; };
|
||||||
# bazarr = base // { };
|
# bazarr = base // { };
|
||||||
jellyfin = base // { };
|
|
||||||
# prowlarr.enable = true;
|
# prowlarr.enable = true;
|
||||||
# jira.enable = true;
|
# jira.enable = true;
|
||||||
# adguardhome = {
|
# adguardhome = {
|
||||||
@ -160,71 +128,6 @@ in {
|
|||||||
# tokenKeyFile = "${pkgs.writeText "kavitaToken"
|
# tokenKeyFile = "${pkgs.writeText "kavitaToken"
|
||||||
# "Au002BRkRxBjlQrmWSuXWTGUcpXZjzMo2nJ0Z4g4OZ1S4c2zp6oaesGUXzKp2mhvOwjju002BNoURG3CRIE2qnGybvOgAlDxAZCPBzSNRcx6RJ1lFRgvI8wQR6Nd5ivYX0RMo4S8yOH8XIDhzN6vNo31rCjyv2IycX0JqiJPIovfbvXn9Y="}";
|
# "Au002BRkRxBjlQrmWSuXWTGUcpXZjzMo2nJ0Z4g4OZ1S4c2zp6oaesGUXzKp2mhvOwjju002BNoURG3CRIE2qnGybvOgAlDxAZCPBzSNRcx6RJ1lFRgvI8wQR6Nd5ivYX0RMo4S8yOH8XIDhzN6vNo31rCjyv2IycX0JqiJPIovfbvXn9Y="}";
|
||||||
# };
|
# };
|
||||||
nextcloud = {
|
|
||||||
enable = true;
|
|
||||||
https = true;
|
|
||||||
package = pkgs.nextcloud29;
|
|
||||||
appstoreEnable = true;
|
|
||||||
configureRedis = true;
|
|
||||||
extraAppsEnable = true;
|
|
||||||
enableImagemagick = true;
|
|
||||||
maxUploadSize = "16G";
|
|
||||||
hostName = "cloud.servidos.lat";
|
|
||||||
extraApps = {
|
|
||||||
inherit (config.services.nextcloud.package.packages.apps) calendar;
|
|
||||||
};
|
|
||||||
config = {
|
|
||||||
adminpassFile = "${pkgs.writeText "adminpass"
|
|
||||||
"Overlying-Hatchback-Charting-Encounter-Deface-Gallantly7"}";
|
|
||||||
dbtype = "pgsql";
|
|
||||||
dbhost = postgresSocket;
|
|
||||||
dbtableprefix = "oc_";
|
|
||||||
dbname = "nextcloud";
|
|
||||||
};
|
|
||||||
phpOptions = {
|
|
||||||
catch_workers_output = "yes";
|
|
||||||
display_errors = "stderr";
|
|
||||||
error_reporting = "E_ALL & ~E_DEPRECATED & ~E_STRICT";
|
|
||||||
expose_php = "Off";
|
|
||||||
"opcache.enable_cli" = "1";
|
|
||||||
"opcache.fast_shutdown" = "1";
|
|
||||||
"opcache.interned_strings_buffer" = "16";
|
|
||||||
"opcache.jit" = "1255";
|
|
||||||
"opcache.jit_buffer_size" = "256M";
|
|
||||||
"opcache.max_accelerated_files" = "10000";
|
|
||||||
"opcache.huge_code_pages" = "1";
|
|
||||||
"opcache.enable_file_override" = "1";
|
|
||||||
"opcache.memory_consumption" = "128";
|
|
||||||
"opcache.revalidate_freq" = "60";
|
|
||||||
"opcache.save_comments" = "1";
|
|
||||||
"opcache.validate_timestamps" = "0";
|
|
||||||
"openssl.cafile" = "/etc/ssl/certs/ca-certificates.crt";
|
|
||||||
short_open_tag = "Off";
|
|
||||||
};
|
|
||||||
settings = {
|
|
||||||
log_type = "file";
|
|
||||||
log_level = 3;
|
|
||||||
trusted_proxies = [ "nginx" ];
|
|
||||||
trusted_domains = [ "cloud.rotehaare.art" "danilo-reyes.com" ];
|
|
||||||
overwrite_protocol = "https";
|
|
||||||
default_phone_region = "MX";
|
|
||||||
"allow_local_remote_servers" = true;
|
|
||||||
mail_smtpmode = "sendmail";
|
|
||||||
mail_sendmailmode = "pipe";
|
|
||||||
"installed" = true;
|
|
||||||
"memories.exiftool" = "/etc/profiles/per-user/nextcloud/bin/exiftool";
|
|
||||||
enabledPreviewProviders = [
|
|
||||||
"OC\\Preview\\Image"
|
|
||||||
"OC\\Preview\\HEIC"
|
|
||||||
"OC\\Preview\\TIFF"
|
|
||||||
"OC\\Preview\\MKV"
|
|
||||||
"OC\\Preview\\MP4"
|
|
||||||
"OC\\Preview\\AVI"
|
|
||||||
"OC\\Preview\\Movie"
|
|
||||||
];
|
|
||||||
};
|
|
||||||
phpExtraExtensions = all: [ all.pdlib all.bz2 all.ldap ];
|
|
||||||
};
|
|
||||||
postgresql = let
|
postgresql = let
|
||||||
dbNames =
|
dbNames =
|
||||||
[ "jawz" "paperless" "nextcloud" "ryot" "vaultwarden" "shiori" ];
|
[ "jawz" "paperless" "nextcloud" "ryot" "vaultwarden" "shiori" ];
|
||||||
@ -245,7 +148,6 @@ in {
|
|||||||
};
|
};
|
||||||
systemd = {
|
systemd = {
|
||||||
services = {
|
services = {
|
||||||
nextcloud-cron.path = [ pkgs.perl ];
|
|
||||||
# sub-sync = {
|
# sub-sync = {
|
||||||
# restartIfChanged = true;
|
# restartIfChanged = true;
|
||||||
# description = "syncronizes subtitles downloaded & modified today";
|
# description = "syncronizes subtitles downloaded & modified today";
|
||||||
@ -259,27 +161,8 @@ in {
|
|||||||
# User = "root";
|
# User = "root";
|
||||||
# };
|
# };
|
||||||
# };
|
# };
|
||||||
nextcloud-cronjob = let
|
|
||||||
nextcloud-cronjob = pkgs.writeScriptBin "nextcloud-cronjob"
|
|
||||||
(builtins.readFile ../../scripts/nextcloud-cronjob.sh);
|
|
||||||
in {
|
|
||||||
description = "Runs various nextcloud-related cronjobs";
|
|
||||||
wantedBy = [ "multi-user.target" ];
|
|
||||||
path = [ pkgs.bash nextcloud-cronjob ];
|
|
||||||
serviceConfig = {
|
|
||||||
Restart = "on-failure";
|
|
||||||
RestartSec = 30;
|
|
||||||
ExecStart = "${nextcloud-cronjob}/bin/nextcloud-cronjob";
|
|
||||||
};
|
|
||||||
};
|
|
||||||
};
|
};
|
||||||
timers = {
|
timers = {
|
||||||
nextcloud-cronjob = {
|
|
||||||
enable = true;
|
|
||||||
description = "Runs various nextcloud-related cronjobs";
|
|
||||||
wantedBy = [ "timers.target" ];
|
|
||||||
timerConfig = { OnCalendar = "*:0/10"; };
|
|
||||||
};
|
|
||||||
# sub-sync = {
|
# sub-sync = {
|
||||||
# enable = true;
|
# enable = true;
|
||||||
# description = "syncronizes subtitles downloaded & modified today";
|
# description = "syncronizes subtitles downloaded & modified today";
|
||||||
|
|||||||
44
modules/servers.nix
Normal file
44
modules/servers.nix
Normal file
@ -0,0 +1,44 @@
|
|||||||
|
{ lib, config, pkgs, ... }:
|
||||||
|
let
|
||||||
|
serviceBase = {
|
||||||
|
enable = true;
|
||||||
|
group = "piracy";
|
||||||
|
};
|
||||||
|
enableDocker = lib.any (opt: opt) [
|
||||||
|
config.my.servers.collabora.enable
|
||||||
|
config.my.servers.go-vod.enable
|
||||||
|
];
|
||||||
|
in {
|
||||||
|
imports = [
|
||||||
|
(import ./servers/jellyfin.nix { inherit lib config pkgs serviceBase; })
|
||||||
|
(import ./servers/nextcloud.nix { inherit lib config pkgs serviceBase; })
|
||||||
|
];
|
||||||
|
options.my.servers.settings = {
|
||||||
|
localhost = "127.0.0.1";
|
||||||
|
domain = "servidos.lat";
|
||||||
|
postgresSocket = "/run/postgresql";
|
||||||
|
};
|
||||||
|
config = {
|
||||||
|
my.servers = {
|
||||||
|
jellyfin.enable = lib.mkDefault false;
|
||||||
|
nextcloud = {
|
||||||
|
enable = lib.mkDefault false;
|
||||||
|
enableCron = lib.mkDefault false;
|
||||||
|
};
|
||||||
|
collabora.enable = lib.mkDefault false;
|
||||||
|
go-vod.enable = lib.mkDefault false;
|
||||||
|
};
|
||||||
|
virtualisation = lib.mkIf enableDocker {
|
||||||
|
oci-containers.backend = "docker";
|
||||||
|
docker = {
|
||||||
|
enable = true;
|
||||||
|
enableNvidia = true;
|
||||||
|
autoPrune = {
|
||||||
|
enable = true;
|
||||||
|
flags = [ "--all" ];
|
||||||
|
dates = "weekly";
|
||||||
|
};
|
||||||
|
};
|
||||||
|
};
|
||||||
|
};
|
||||||
|
}
|
||||||
14
modules/servers/docker.nix
Normal file
14
modules/servers/docker.nix
Normal file
@ -0,0 +1,14 @@
|
|||||||
|
{ ... }: {
|
||||||
|
virtualization = {
|
||||||
|
oci-containers.backend = "docker";
|
||||||
|
docker = {
|
||||||
|
enable = true;
|
||||||
|
enableNvidia = true;
|
||||||
|
autoPrune = {
|
||||||
|
enable = true;
|
||||||
|
flags = [ "--all" ];
|
||||||
|
dates = "weekly";
|
||||||
|
};
|
||||||
|
};
|
||||||
|
};
|
||||||
|
}
|
||||||
103
modules/servers/jellyfin.nix
Normal file
103
modules/servers/jellyfin.nix
Normal file
@ -0,0 +1,103 @@
|
|||||||
|
{ lib, config, pkgs, serviceBase, ... }:
|
||||||
|
let
|
||||||
|
localhost = config.my.servers.settings.localhost;
|
||||||
|
port = 8096;
|
||||||
|
in {
|
||||||
|
options.my.servers.jellyfin.enable = lib.mkEnableOption "enable";
|
||||||
|
config = lib.mkIf config.my.servers.jellyfin.enable {
|
||||||
|
environment.systemPackages = [ pkgs.jellyfin-ffmpeg ];
|
||||||
|
services = {
|
||||||
|
jellyfin = serviceBase // { };
|
||||||
|
nginx = {
|
||||||
|
enable = true;
|
||||||
|
appendHttpConfig = ''
|
||||||
|
# JELLYFIN
|
||||||
|
proxy_cache_path /var/cache/nginx/jellyfin-videos levels=1:2 keys_zone=jellyfin-videos:100m inactive=90d max_size=35000m;
|
||||||
|
proxy_cache_path /var/cache/nginx/jellyfin levels=1:2 keys_zone=jellyfin:100m max_size=15g inactive=30d use_temp_path=off;
|
||||||
|
map $request_uri $h264Level { ~(h264-level=)(.+?)& $2; }
|
||||||
|
map $request_uri $h264Profile { ~(h264-profile=)(.+?)& $2; }
|
||||||
|
'';
|
||||||
|
virtualHosts = {
|
||||||
|
"flix.${config.my.servers.settings.domain}" = {
|
||||||
|
forceSSL = true;
|
||||||
|
enableACME = true;
|
||||||
|
http2 = true;
|
||||||
|
extraConfig = ''
|
||||||
|
# use a variable to store the upstream proxy
|
||||||
|
# in this example we are using a hostname which is resolved via DNS
|
||||||
|
# (if you aren't using DNS remove the resolver line and change the variable to point to an IP address
|
||||||
|
resolver ${localhost} valid=30;
|
||||||
|
|
||||||
|
location = / {
|
||||||
|
return 302 http://$host/web/;
|
||||||
|
#return 302 https://$host/web/;
|
||||||
|
}
|
||||||
|
|
||||||
|
location = /web/ {
|
||||||
|
# Proxy main Jellyfin traffic
|
||||||
|
proxy_pass http://${localhost}:${toString port}/web/index.html;
|
||||||
|
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_set_header X-Forwarded-Proto $scheme;
|
||||||
|
proxy_set_header X-Forwarded-Protocol $scheme;
|
||||||
|
proxy_set_header X-Forwarded-Host $http_host;
|
||||||
|
}
|
||||||
|
'';
|
||||||
|
locations = {
|
||||||
|
"/" = {
|
||||||
|
proxyPass = "http://${localhost}:${toString port}";
|
||||||
|
proxyWebsockets = true;
|
||||||
|
};
|
||||||
|
"/socket" = {
|
||||||
|
proxyPass = "http://${localhost}:${toString port}";
|
||||||
|
extraConfig = ''
|
||||||
|
proxy_http_version 1.1;
|
||||||
|
proxy_set_header Upgrade $http_upgrade;
|
||||||
|
proxy_set_header Connection "upgrade";
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
"~ /Items/(.*)/Images" = {
|
||||||
|
proxyPass = "http://${localhost}:${toString port}";
|
||||||
|
extraConfig = ''
|
||||||
|
proxy_cache jellyfin;
|
||||||
|
proxy_cache_revalidate on;
|
||||||
|
proxy_cache_lock on;
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
"~* ^/Videos/(.*)/(?!live)" = {
|
||||||
|
proxyPass = "http://${localhost}:${toString port}";
|
||||||
|
extraConfig = ''
|
||||||
|
# Set size of a slice (this amount will be always requested from the backend by nginx)
|
||||||
|
# Higher value means more latency, lower more overhead
|
||||||
|
# This size is independent of the size clients/browsers can request
|
||||||
|
# slice 2m;
|
||||||
|
|
||||||
|
proxy_cache jellyfin-videos;
|
||||||
|
proxy_cache_valid 200 206 301 302 30d;
|
||||||
|
proxy_ignore_headers Expires Cache-Control Set-Cookie X-Accel-Expires;
|
||||||
|
proxy_cache_use_stale error timeout invalid_header updating http_500 http_502 http_503 http_504;
|
||||||
|
proxy_connect_timeout 15s;
|
||||||
|
proxy_http_version 1.1;
|
||||||
|
proxy_set_header Connection "";
|
||||||
|
# Transmit slice range to the backend
|
||||||
|
proxy_set_header Range 2m;
|
||||||
|
|
||||||
|
# This saves bandwidth between the proxy and jellyfin, as a file is only downloaded one time instead of multiple times when multiple clients want to at the same time
|
||||||
|
# The first client will trigger the download, the other clients will have to wait until the slice is cached
|
||||||
|
# Esp. practical during SyncPlay
|
||||||
|
proxy_cache_lock on;
|
||||||
|
proxy_cache_lock_age 60s;
|
||||||
|
|
||||||
|
proxy_cache_key "jellyvideo$uri?MediaSourceId=$arg_MediaSourceId&VideoCodec=$arg_VideoCodec&AudioCodec=$arg_AudioCodec&AudioStreamIndex=$arg_AudioStreamIndex&VideoBitrate=$arg_VideoBitrate&AudioBitrate=$arg_AudioBitrate&SubtitleMethod=$arg_SubtitleMethod&TranscodingMaxAudioChannels=$arg_TranscodingMaxAudioChannels&RequireAvc=$arg_RequireAvc&SegmentContainer=$arg_SegmentContainer&MinSegments=$arg_MinSegments&BreakOnNonKeyFrames=$arg_BreakOnNonKeyFrames&h264-profile=$h264Profile&h264-level=$h264Level&slicerange=2m";
|
||||||
|
|
||||||
|
# add_header X-Cache-Status $upstream_cache_status; # This is only for debugging cache
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
};
|
||||||
|
};
|
||||||
|
};
|
||||||
|
};
|
||||||
|
};
|
||||||
|
};
|
||||||
|
}
|
||||||
222
modules/servers/nextcloud.nix
Normal file
222
modules/servers/nextcloud.nix
Normal file
@ -0,0 +1,222 @@
|
|||||||
|
{ lib, config, pkgs, serviceBase, ... }:
|
||||||
|
let
|
||||||
|
localhost = config.my.servers.settings.localhost;
|
||||||
|
collaboraPort = 9980;
|
||||||
|
in {
|
||||||
|
options.my.servers = {
|
||||||
|
nextcloud = {
|
||||||
|
enable = lib.mkEnableOption "enable";
|
||||||
|
enableCron = lib.mkEnableOption "enable";
|
||||||
|
};
|
||||||
|
collabora.enable = lib.mkEnableOption "enable";
|
||||||
|
go-vod.enable = lib.mkEnableOption "enable";
|
||||||
|
};
|
||||||
|
config = lib.mkIf
|
||||||
|
(config.my.servers.nextcloud.enable && config.my.servers.postgres.enable) {
|
||||||
|
environment.systemPackages = with pkgs; [ mediainfo dlib ];
|
||||||
|
users.users.nextcloud = {
|
||||||
|
isSystemUser = true;
|
||||||
|
extraGroups = [ "render" ];
|
||||||
|
packages = (with pkgs; [
|
||||||
|
nodejs
|
||||||
|
(python3.withPackages (ps: with ps; [ tensorflow ]))
|
||||||
|
perl
|
||||||
|
(perlPackages.buildPerlPackage rec {
|
||||||
|
pname = "Image-ExifTool";
|
||||||
|
version = "12.70";
|
||||||
|
src = fetchurl {
|
||||||
|
url = "https://exiftool.org/Image-ExifTool-${version}.tar.gz";
|
||||||
|
hash = "sha256-TLJSJEXMPj870TkExq6uraX8Wl4kmNerrSlX3LQsr/4=";
|
||||||
|
};
|
||||||
|
})
|
||||||
|
]);
|
||||||
|
};
|
||||||
|
programs.msmtp = {
|
||||||
|
enable = true;
|
||||||
|
accounts.default = {
|
||||||
|
auth = true;
|
||||||
|
host = "smtp.gmail.com";
|
||||||
|
port = 587;
|
||||||
|
tls = true;
|
||||||
|
from = "stunner6399@gmail.com";
|
||||||
|
user = "stunner6399@gmail.com";
|
||||||
|
password = "eqyctcgjdykqeuwt";
|
||||||
|
};
|
||||||
|
};
|
||||||
|
services = {
|
||||||
|
nextcloud = {
|
||||||
|
enable = true;
|
||||||
|
https = true;
|
||||||
|
package = pkgs.nextcloud29;
|
||||||
|
appstoreEnable = true;
|
||||||
|
configureRedis = true;
|
||||||
|
extraAppsEnable = true;
|
||||||
|
enableImagemagick = true;
|
||||||
|
maxUploadSize = "16G";
|
||||||
|
hostName = "cloud.servidos.lat";
|
||||||
|
extraApps = {
|
||||||
|
inherit (config.services.nextcloud.package.packages.apps) calendar;
|
||||||
|
};
|
||||||
|
config = {
|
||||||
|
adminpassFile = "${pkgs.writeText "adminpass"
|
||||||
|
"Overlying-Hatchback-Charting-Encounter-Deface-Gallantly7"}";
|
||||||
|
dbtype = "pgsql";
|
||||||
|
dbhost = config.my.servers.settings.postgresSocket;
|
||||||
|
dbtableprefix = "oc_";
|
||||||
|
dbname = "nextcloud";
|
||||||
|
};
|
||||||
|
phpOptions = {
|
||||||
|
catch_workers_output = "yes";
|
||||||
|
display_errors = "stderr";
|
||||||
|
error_reporting = "E_ALL & ~E_DEPRECATED & ~E_STRICT";
|
||||||
|
expose_php = "Off";
|
||||||
|
"opcache.enable_cli" = "1";
|
||||||
|
"opcache.fast_shutdown" = "1";
|
||||||
|
"opcache.interned_strings_buffer" = "16";
|
||||||
|
"opcache.jit" = "1255";
|
||||||
|
"opcache.jit_buffer_size" = "256M";
|
||||||
|
"opcache.max_accelerated_files" = "10000";
|
||||||
|
"opcache.huge_code_pages" = "1";
|
||||||
|
"opcache.enable_file_override" = "1";
|
||||||
|
"opcache.memory_consumption" = "128";
|
||||||
|
"opcache.revalidate_freq" = "60";
|
||||||
|
"opcache.save_comments" = "1";
|
||||||
|
"opcache.validate_timestamps" = "0";
|
||||||
|
"openssl.cafile" = "/etc/ssl/certs/ca-certificates.crt";
|
||||||
|
short_open_tag = "Off";
|
||||||
|
};
|
||||||
|
settings = {
|
||||||
|
log_type = "file";
|
||||||
|
log_level = 3;
|
||||||
|
trusted_proxies = [ "nginx" ];
|
||||||
|
trusted_domains = [ "cloud.rotehaare.art" "danilo-reyes.com" ];
|
||||||
|
overwrite_protocol = "https";
|
||||||
|
default_phone_region = "MX";
|
||||||
|
"allow_local_remote_servers" = true;
|
||||||
|
mail_smtpmode = "sendmail";
|
||||||
|
mail_sendmailmode = "pipe";
|
||||||
|
"installed" = true;
|
||||||
|
"memories.exiftool" =
|
||||||
|
"/etc/profiles/per-user/nextcloud/bin/exiftool";
|
||||||
|
enabledPreviewProviders = [
|
||||||
|
"OC\\Preview\\Image"
|
||||||
|
"OC\\Preview\\HEIC"
|
||||||
|
"OC\\Preview\\TIFF"
|
||||||
|
"OC\\Preview\\MKV"
|
||||||
|
"OC\\Preview\\MP4"
|
||||||
|
"OC\\Preview\\AVI"
|
||||||
|
"OC\\Preview\\Movie"
|
||||||
|
];
|
||||||
|
};
|
||||||
|
phpExtraExtensions = all: [ all.pdlib all.bz2 all.ldap ];
|
||||||
|
};
|
||||||
|
nginx = {
|
||||||
|
enable = true;
|
||||||
|
virtualHosts = {
|
||||||
|
${config.services.nextcloud.hostName} = {
|
||||||
|
forceSSL = true;
|
||||||
|
enableACME = true;
|
||||||
|
http2 = true;
|
||||||
|
serverAliases = [ "cloud.rotehaare.art" ];
|
||||||
|
locations = {
|
||||||
|
"/".proxyWebsockets = true;
|
||||||
|
"~ ^/nextcloud/(?:index|remote|public|cron|core/ajax/update|status|ocs/v[12]|updater/.+|oc[ms]-provider/.+|.+/richdocumentscode/proxy).php(?:$|/)" =
|
||||||
|
{ };
|
||||||
|
};
|
||||||
|
};
|
||||||
|
"collabora.${config.my.servers.settings.domain}" = let
|
||||||
|
localUrl = "http://${localhost}:${toString collaboraPort}";
|
||||||
|
proxySettings = {
|
||||||
|
proxyPass = localUrl;
|
||||||
|
extraConfig = ''
|
||||||
|
proxy_set_header Host $host;
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
collaboraSocket = {
|
||||||
|
proxyPass = localUrl;
|
||||||
|
extraConfig = ''
|
||||||
|
proxy_set_header Upgrade $http_upgrade;
|
||||||
|
proxy_set_header Connection "Upgrade";
|
||||||
|
proxy_set_header Host $host;
|
||||||
|
proxy_read_timeout 36000s;
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
in serviceBase lib.mkIf config.my.servers.collabora.enable {
|
||||||
|
# static files
|
||||||
|
"^~ /loleaflet" = proxySettings;
|
||||||
|
# WOPI discovery URL
|
||||||
|
"^~ /hosting/discovery" = proxySettings;
|
||||||
|
# Capabilities
|
||||||
|
"^~ /hosting/capabilities" = proxySettings;
|
||||||
|
# download, presentation, image upload and websocket
|
||||||
|
"~ ^/lool" = collaboraSocket;
|
||||||
|
# Admin Console websocket
|
||||||
|
"^~ /lool/adminws" = collaboraSocket;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
};
|
||||||
|
};
|
||||||
|
virtualisation.oci-containers.containers = {
|
||||||
|
go-vod = lib.mkIf config.my.servers.go-vod.enable {
|
||||||
|
autoStart = true;
|
||||||
|
image = "radialapps/go-vod";
|
||||||
|
environment = {
|
||||||
|
TZ = "America/Mexico_City";
|
||||||
|
NEXTCLOUD_HOST = "https://${config.services.nextcloud.hostName}";
|
||||||
|
NVIDIA_VISIBLE_DEVICES = "all";
|
||||||
|
};
|
||||||
|
volumes = [ "ncdata:/var/www/html:ro" ];
|
||||||
|
extraOptions = [
|
||||||
|
"--device=/dev/dri" # VA-API (omit for NVENC)
|
||||||
|
];
|
||||||
|
};
|
||||||
|
collabora = lib.mkIf config.my.servers.collabora.enable {
|
||||||
|
autoStart = true;
|
||||||
|
image = "collabora/code";
|
||||||
|
imageFile = pkgs.dockerTools.pullImage {
|
||||||
|
imageName = "collabora/code";
|
||||||
|
imageDigest =
|
||||||
|
"sha256:aab41379baf5652832e9237fcc06a768096a5a7fccc66cf8bd4fdb06d2cbba7f";
|
||||||
|
sha256 = "sha256-M66lynhzaOEFnE15Sy1N6lBbGDxwNw6ap+IUJAvoCLs=";
|
||||||
|
};
|
||||||
|
ports = [ "9980:9980" ];
|
||||||
|
environment = {
|
||||||
|
TZ = "America/Mexico_City";
|
||||||
|
domain = "cloud.servidos.lat";
|
||||||
|
aliasgroup1 = "cloud.servidos.lat:443";
|
||||||
|
aliasgroup2 = "cloud.rotehaare.art:443";
|
||||||
|
dictionaries = "en_CA en_US es_MX es_ES fr_FR it pt_BR ru";
|
||||||
|
extra_params = ''
|
||||||
|
--o:ssl.enable=false
|
||||||
|
--o:ssl.termination=true
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
extraOptions = [ "--cap-add" "MKNOD" ];
|
||||||
|
};
|
||||||
|
};
|
||||||
|
systemd = lib.mkIf config.my.servers.nextcloud.enableCron {
|
||||||
|
services = {
|
||||||
|
nextcloud-cron.path = [ pkgs.perl ];
|
||||||
|
nextcloud-cronjob = let
|
||||||
|
nextcloud-cronjob = pkgs.writeScriptBin "nextcloud-cronjob"
|
||||||
|
(builtins.readFile ../../scripts/nextcloud-cronjob.sh);
|
||||||
|
in {
|
||||||
|
description = "Runs various nextcloud-related cronjobs";
|
||||||
|
wantedBy = [ "multi-user.target" ];
|
||||||
|
path = [ pkgs.bash nextcloud-cronjob ];
|
||||||
|
serviceConfig = {
|
||||||
|
Restart = "on-failure";
|
||||||
|
RestartSec = 30;
|
||||||
|
ExecStart = "${nextcloud-cronjob}/bin/nextcloud-cronjob";
|
||||||
|
};
|
||||||
|
};
|
||||||
|
};
|
||||||
|
timers.nextcloud-cronjob = {
|
||||||
|
enable = true;
|
||||||
|
description = "Runs various nextcloud-related cronjobs";
|
||||||
|
wantedBy = [ "timers.target" ];
|
||||||
|
timerConfig = { OnCalendar = "*:0/10"; };
|
||||||
|
};
|
||||||
|
};
|
||||||
|
};
|
||||||
|
}
|
||||||
@ -1 +0,0 @@
|
|||||||
{ config, lib, pkgs, ... }: { users.users.jawz.packages = with pkgs; ([ ]); }
|
|
||||||
Loading…
x
Reference in New Issue
Block a user