Code change:
${optionalString cfg.caching.apcu "'memcache.local' => 'OCMemcacheAPCu',"} 'log_type' => 'syslog', 'log_level' => '${builtins.toString cfg.logLevel}', <del> ${optionalString (cfg.config.overwriteProtocol != null) "'overwriteprotocol' => '${cfg.config.overwriteProtocol}',"} </del> <ins> ${optionalString (c.overwriteProtocol != null) "'overwriteprotocol' => '${c.overwriteProtocol}',"} ${optionalString (c.dbname != null) "'dbname' => '${c.dbname}',"} ${optionalString (c.dbhost != null) "'dbhost' => '${c.dbhost}',"} ${optionalString (c.dbport != null) "'dbport' => '${toString c.dbport}',"} ${optionalString (c.dbuser != null) "'dbuser' => '${c.dbuser}',"} ${optionalString (c.dbtableprefix != null) "'dbtableprefix' => '${toString c.dbtableprefix}',"} ${optionalString (c.dbpass != null) "'dbpassword' => '${c.dbpass}',"} ${optionalString (c.dbpassFile != null) "'dbpassword' => nix_read_pwd(),"} 'dbtype' => '${c.dbtype}', 'trusted_domains' => ${writePhpArrary c.extraTrustedDomains}, </ins> ]; ''; occInstallCmd = let <del> c = cfg.config; adminpass = if c.adminpassFile != null then ''"$(<"${toString c.adminpassFile}")"'' else ''"${toString c.adminpass}"''; </del> dbpass = if c.dbpassFile != null then ''"$(<"${toString c.dbpassFile}")"'' else if c.dbpass != null then ''"${toString c.dbpass}"'' else null; <ins> adminpass = if c.adminpassFile != null then ''"$(<"${toString c.adminpassFile}")"'' else ''"${toString c.adminpass}"''; </ins> installFlags = concatStringsSep " n    " (mapAttrsToList (k: v: "${k} ${toString v}") { "--database" = ''"${c.dbtype}"'';

Related discussion:
text: If I'm not missing something obvious, checking configuration changes would translate to parsing/evaluating on every nextcloud startup as an , comparing every "interesting" key with the one provided through nixos configuration, and eventually then bailing out if they differ. I'm not sure if that's a road we'd like to go and keep up to date, while the underlying bug is a missing distinction between configuration and state upstream…
Since upstream mixes state and config it's questionable whether their configuration format is somehow supposed to be backwards-compatible (as it's only supposed to be used internally by Nextcloud). Hence I'm afraid that this will make i.e. upgrades even harder in case of configuration changes, so :-1: from me. As the issues are documented in the manual now, folks are warned and I think that this is a better option in contrast to adding more complexity to . I suggest we either close this for the reasons already stated or wait for an appropriate upstream fix.
I really don't feel good having stuff in that's actually a disguised command line… :/ Something that would sound nicer to me would be an executable that the user would have to manually run, and a bare-bones module that does not handle setup or configuration and just makes sure that the systemd unit is setup. At least the error is obvious (enabling the module without having run the executable would fail), all module options actually mean something, and the impure operation is made explicit. Either that or, similar to , rename all the options so it's explicit that they're used only for initial configuration. Would one of these solutions make sense to you?
Me neither, but currently we don't have much choice… I really like the fact that we can set up the Nextcloud instance in an unattended fashion, without having to worry about manual setting things up. I really don't want to end with more imperative setup steps than necessary. In theory, we could move some of the options in to to make it more obvious what isn't applied continuously. But TBH, I'd rather like to see the state/config mixing fixed upstream than having to introduce more mental complexity here, especially if this gets fixed and we end up with both incarnations. Really, this issue only occurs while a user changes nextcloud database parameters (mostly while tweaking his initial setup), and not having read the module documentation, where the behaviour is documented.