From a24ed21f39daa5599b52354ebcf73c1bba5f5df1 Mon Sep 17 00:00:00 2001 From: Danilo Reyes Date: Fri, 14 Jun 2024 15:09:36 -0600 Subject: [PATCH] nginx & jellyfin modularized --- base.nix | 1 + hosts/miniserver/configuration.nix | 7 +- hosts/miniserver/docker.nix | 39 ----- hosts/miniserver/nginx.nix | 131 ----------------- hosts/miniserver/servers.nix | 117 --------------- modules/servers.nix | 44 ++++++ modules/servers/docker.nix | 14 ++ modules/servers/jellyfin.nix | 103 +++++++++++++ modules/servers/nextcloud.nix | 222 +++++++++++++++++++++++++++++ modules/template.nix | 1 - 10 files changed, 385 insertions(+), 294 deletions(-) create mode 100644 modules/servers.nix create mode 100644 modules/servers/docker.nix create mode 100644 modules/servers/jellyfin.nix create mode 100644 modules/servers/nextcloud.nix delete mode 100644 modules/template.nix diff --git a/base.nix b/base.nix index 31e5960..cc7cf3d 100644 --- a/base.nix +++ b/base.nix @@ -5,6 +5,7 @@ ./modules/dev.nix ./modules/shell.nix ./modules/services.nix + ./modules/servers.nix ./modules/scripts.nix ./jawz.nix ]; diff --git a/hosts/miniserver/configuration.nix b/hosts/miniserver/configuration.nix index 479d5fe..f3028ab 100644 --- a/hosts/miniserver/configuration.nix +++ b/hosts/miniserver/configuration.nix @@ -92,12 +92,7 @@ ]; }; }; - environment.systemPackages = with pkgs; [ - wget - jellyfin-ffmpeg # coolest video converter! - mediainfo # nextcloud - dlib - ]; + environment.systemPackages = with pkgs; [ wget ]; services = { btrfs.autoScrub.fileSystems = [ "/mnt/pool" ]; # minidlna = { diff --git a/hosts/miniserver/docker.nix b/hosts/miniserver/docker.nix index bd693a3..fffe105 100644 --- a/hosts/miniserver/docker.nix +++ b/hosts/miniserver/docker.nix @@ -7,8 +7,6 @@ docker = { enable = true; enableNvidia = true; - # dockerCompat = true; - # defaultNetwork.settings.dns_enabled = true; autoPrune = { enable = true; flags = [ "--all" ]; @@ -16,31 +14,7 @@ }; }; oci-containers = { - backend = "docker"; 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 = { # image = "ghcr.io/alexta69/metube"; # ports = [ "8881:8081" ]; @@ -209,19 +183,6 @@ "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) - ]; - }; }; }; }; diff --git a/hosts/miniserver/nginx.nix b/hosts/miniserver/nginx.nix index f353107..cce3cdf 100644 --- a/hosts/miniserver/nginx.nix +++ b/hosts/miniserver/nginx.nix @@ -7,10 +7,7 @@ let localhost = "127.0.0.1"; # workstation = "192.168.1.64"; domain = "servidos.lat"; - jellyfinPort = 8096; shioriPort = 4368; - # nextcloudPort = 80; - collaboraPort = 9980; flamePort = 5005; secretFlamePort = 5007; # lidarrPort = 8686; @@ -37,13 +34,6 @@ in { # recommendedGzipSettings = true; # recommendedOptimisation = true; 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 base = 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 = { diff --git a/hosts/miniserver/servers.nix b/hosts/miniserver/servers.nix index 0abc55c..c7f56d7 100644 --- a/hosts/miniserver/servers.nix +++ b/hosts/miniserver/servers.nix @@ -39,7 +39,6 @@ in { "$@" '') ]; - users.groups = { piracy.gid = 985; }; users.users = let base = { isSystemUser = true; }; in { # # prowlarr = base // { group = "piracy"; }; @@ -47,36 +46,6 @@ in { # # group = "kavita"; # # 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 base = { @@ -87,7 +56,6 @@ in { # sonarr = base // { package = pkgs.sonarr; }; # radarr = base // { package = pkgs.radarr; }; # bazarr = base // { }; - jellyfin = base // { }; # prowlarr.enable = true; # jira.enable = true; # adguardhome = { @@ -160,71 +128,6 @@ in { # tokenKeyFile = "${pkgs.writeText "kavitaToken" # "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 dbNames = [ "jawz" "paperless" "nextcloud" "ryot" "vaultwarden" "shiori" ]; @@ -245,7 +148,6 @@ in { }; systemd = { services = { - nextcloud-cron.path = [ pkgs.perl ]; # sub-sync = { # restartIfChanged = true; # description = "syncronizes subtitles downloaded & modified today"; @@ -259,27 +161,8 @@ in { # 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 = { - nextcloud-cronjob = { - enable = true; - description = "Runs various nextcloud-related cronjobs"; - wantedBy = [ "timers.target" ]; - timerConfig = { OnCalendar = "*:0/10"; }; - }; # sub-sync = { # enable = true; # description = "syncronizes subtitles downloaded & modified today"; diff --git a/modules/servers.nix b/modules/servers.nix new file mode 100644 index 0000000..b82d730 --- /dev/null +++ b/modules/servers.nix @@ -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"; + }; + }; + }; + }; +} diff --git a/modules/servers/docker.nix b/modules/servers/docker.nix new file mode 100644 index 0000000..43bad3e --- /dev/null +++ b/modules/servers/docker.nix @@ -0,0 +1,14 @@ +{ ... }: { + virtualization = { + oci-containers.backend = "docker"; + docker = { + enable = true; + enableNvidia = true; + autoPrune = { + enable = true; + flags = [ "--all" ]; + dates = "weekly"; + }; + }; + }; +} diff --git a/modules/servers/jellyfin.nix b/modules/servers/jellyfin.nix new file mode 100644 index 0000000..d1c27de --- /dev/null +++ b/modules/servers/jellyfin.nix @@ -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 + ''; + }; + }; + }; + }; + }; + }; + }; +} diff --git a/modules/servers/nextcloud.nix b/modules/servers/nextcloud.nix new file mode 100644 index 0000000..caf66d4 --- /dev/null +++ b/modules/servers/nextcloud.nix @@ -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"; }; + }; + }; + }; +} diff --git a/modules/template.nix b/modules/template.nix deleted file mode 100644 index 7a2e40f..0000000 --- a/modules/template.nix +++ /dev/null @@ -1 +0,0 @@ -{ config, lib, pkgs, ... }: { users.users.jawz.packages = with pkgs; ([ ]); }