{ config, pkgs, lib, ... }: let cfg = config.services.nextcloud; hostName = "cloud.feal.no"; in { services.nextcloud = { enable = true; package = pkgs.nextcloud29; inherit hostName; home = "/tank/nextcloud"; https = true; webfinger = true; config = { dbtype = "pgsql"; dbuser = "nextcloud"; dbhost = "/run/postgresql"; dbname = "nextcloud"; adminuser = "ncadmin"; adminpassFile = config.sops.secrets."nextcloud/adminpass".path; }; settings = { default_phone_region = "NO"; log_type = "file"; overwriteprotocol = "https"; trusted_proxies = [ "192.168.10.175" ]; # defiant # Docs: https://github.com/pulsejet/nextcloud-oidc-login oidc_login_auto_redirect = true; oidc_login_button_text = "Log in with KeyCloak"; oidc_login_client_id = "nextcloud"; oidc_login_client_secret = "dont_put_secrets_here_use_secretFile"; oidc_login_code_challenge_method = "S256"; oidc_login_end_session_redirect' = true; oidc_login_logout_url = "https://cloud.feal.no/apps/oidc_login/oidc"; oidc_login_provider_url = "https://iam.feal.no/realms/feal.no"; oidc_login_redir_fallback = true; oidc_login_attributes = { id = "preferred_username"; mail = "email"; name = "name"; login_filter = "nextcloud-roles"; }; oidc_login_filter_allowed_values = [ "nextcloud-user" ]; oidc_login_disable_registration = false; "memories.exiftool" = "${cfg.home}/store-apps/memories/bin-ext/exiftool-amd64-glibc"; "memories.exiftool_no_local" = false; "memories.vod.disable" = false; "memories.vod.ffmpeg" = "${lib.getExe pkgs.ffmpeg-headless}"; "memories.vod.ffprobe" = "${pkgs.ffmpeg-headless}/bin/ffprobe"; preview_ffmpeg_path = "${pkgs.ffmpeg-headless}/bin/ffmpeg"; }; secretFile = config.sops.secrets."nextcloud/secretsjson".path; phpOptions = { "opcache.interned_strings_buffer" = "16"; "upload_max_filesize" = lib.mkForce "8G"; "post_max_size" = lib.mkForce "8G"; "memory_limit" = lib.mkForce "8G"; }; poolSettings = { "pm" = "ondemand"; "pm.max_children" = 32; "pm.process_idle_timeout" = "10s"; "pm.max_requests" = 500; }; }; environment.systemPackages = [ cfg.occ # "occ CMD" in the docs -> "sudo -u nextcloud nextcloud-occ CMD" pkgs.nodejs_20 # For Recognize; Put /run/current-system/sw/bin/node in the "node_binary" field in the web UI -> Memories ]; sops.secrets."nextcloud/adminpass" = { mode = "0440"; owner = "nextcloud"; group = "nextcloud"; restartUnits = [ "phpfpm-nextcloud.service" ]; }; sops.secrets."nextcloud/secretsjson" = { mode = "0440"; owner = "nextcloud"; group = "nextcloud"; restartUnits = [ "phpfpm-nextcloud.service" ]; }; services.postgresql = { ensureDatabases = [ "nextcloud" ]; ensureUsers = [ { name = "nextcloud"; ensureDBOwnership = true; } ]; }; systemd.services.nextcloud-cron = { path = with pkgs; [ exiftool ffmpeg-headless ]; }; systemd.services."nextcloud-setup" = { requires = [ "postgresql.service" ]; after = [ "postgresql.service" ]; }; systemd.services."phpfpm-nextcloud" = { requires = [ "tank-nextcloud.mount" ]; path = with pkgs; [ # perl # perlPackages.ImageExifTool exiftool ffmpeg-headless ]; serviceConfig = { PrivateDevices = lib.mkForce false; WorkingDirectory = "/tank/nextcloud"; NoNewPrivileges = true; PrivateMounts = true; PrivateTmp = true; ProtectClock = true; ProtectHome = true; ProtectHostname = true; ProtectKernelLogs = true; ProtectKernelModules = true; ProtectKernelTunables = true; ProtectProc = "invisible"; ReadWritePaths = [ "/tank/nextcloud" "/run/phpfpm" "/run/systemd" ]; ReadOnlyPaths = [ "/run/secrets" "/nix/store" ]; InaccessbilePaths = [ "/tank/media" "/tank/backup" ]; RemoveIPC = true; RestrictSUIDSGID = true; UMask = "0007"; SystemCallArchitectures = "native"; SystemCallFilter = "@system-service"; CapabilityBoundingSet = "~CAP_FSETID ~CAP_SETFCAP ~CAP_SETUID ~CAP_SETGID ~CAP_SETPCAP ~CAP_NET_ADMIN ~CAP_SYS_ADMIN ~CAP_SYS_PTRACE "; }; }; # Notes: # - Install Memories and Recognize from the app store # - They might need to be forced on with "nextcloud-occ app:enable memories", etc. # - Run "nextcloud-occ maintenance:repair" to fix broken paths # - Download ai models and maps with the commands given in the ui # - libtensorflow doesn't work properly through node, but recognize still works(?) }