Change:
I tried the new nextcloud service on nixos-unstable but seems like it lacks an assert or forgets to create group for nginx since this simple config generates a deployment failure (deployed via nixops):
This could be fixed by making these configurable:
Right, this should be configurable and default to nginx if enabled, complaining if nginx is disabled and it's still set to nginx. Could one of you prepare a PR for that, possibly also editing tests, adding a variant with another webserver?
couldn't it default to another group than nginx and use nginx only if activated ? I was just trying out the module with the hope it would be straigthforward to setup so I don't think I will contribute in the short future.
it might work, but this would mean when enabling nginx, seafile's php would suddenly be executed as another user, yielding weird results due to wrong ownership of files in users data directories - I'd like to avoid that… Examples, like the VM tests, currently also enable - We could also think about enabling automatically when enabling , or make that configurable (and default to true). Do you use apache as webserver, or why don't you use ?
I've enabled nginx and deployed nextcloud on one of my machine. A quick run in journalctl shows no error (and nextcloud yet I can't access the webUI. Is there anything required to enable the webui ? I've used a fake domainName "" since my server has no domain. Could that be it ? should I address it by its IP instead ?
if nextcloud is enabled, the nextcloud module creates a with name pointing to the nextcloud installation.
That might be a bit out of scope but I tried installing nextcloud on several machines and while it seems to work locally (as in wget http://localhost), it doesn't answer to remote connections. I ran wireshark and the server returns no answer. journalctl -b0 shows my connection attempts are blocked: I looked for an nginx.firewall = enable option but that doesn't seem the case. There is a firewallfilter but I would rather enable it via a boolean than using scary iptables parameters.
about that issue, you need to open port 80/443 in the firewall, see :
That solved it thanks. I've a setting for it. Feel free to close it but I like the coupling between the module and the firewall ports opening: Btw I am so glad I switched to nixos. The ease of installation of programs as complex as nextcloud is spectacular (and I expect the maintenance a lot easier as well). This is the kind of selfhosted program I've always wanted to do but didn't want to commit the required time because of software complexity back on ubuntu.
what's your opinion on the missing group issue in case is not enabled? While looking at roundcube, we just went with enabling nginx as soon as the roundcube module is enabled, i think this can (and should) be done here too.
no strong opinion there. Having it work by default is an improvement but what if you disable nginx (a cornercase I admit) ? you will end up with the same error.
you won't easily be able to disable nginx, as it'll be enabled by the nextcloud module automatically.
cc
what do you think about this one?
That's not right AFAICS. You can declare . So, as far as I understand, this issue is about the case where nextcloud is enabled, but nginx is disabled (and therefore phpfpm tries to use the non-existing group), right? In that case we could make nextcloud's group configurable (and set as default) and throw an eval-error if is disabled and no alternative value is declared, right? But is IMHO more experienced with phpfpm and probably has a better idea :)
We still don't have a good answer to running web applications in a more generalized fashion (ie. web server agnostic, or at least supporting multiple web servers), so I would suggest at this point if we can't fully support it we don't support it at all. If someone wants to write a (or whatever) endpoint for then we can add and support that, but as it stands there isn't much of a point to do this... is there?
The universal web service idea is tracked in , I think we should move the discussion around that into this. As nextcloud currently doesn't really work without nginx, we should probably just flip the default of to true, and update the option description to say it's currently not really possible to do it differently, so people will know they might run into problems when still disabling it. WDYT?

Discussion:
inherit (config.system) stateVersion; in { <ins> imports = [ ( mkRemovedOptionModule [ "services" "nextcloud" "nginx" "enable" ] "The nextcloud module dropped support for other webservers than nginx.") ]; </ins> options.services.nextcloud = { enable = mkEnableOption "nextcloud"; hostName = mkOption {

''; }; <del> nginx.enable = mkOption { type = types.bool; default = false; description = '' Whether to enable nginx virtual host management. Further nginx configuration can be done by adapting <literal>services.nginx.virtualHosts.&lt;name&gt;</literal>. See <xref linkend="opt-services.nginx.virtualHosts"/> for further information. ''; }; </del> webfinger = mkOption { type = types.bool; default = false;

script = '' chmod og+x ${cfg.home} ln -sf ${cfg.package}/apps ${cfg.home}/ <del> mkdir -p ${cfg.home}/config ${cfg.home}/data ${cfg.home}/store-apps ln -sf ${overrideConfig} ${cfg.home}/config/override.config.php chown -R nextcloud:nginx ${cfg.home}/config ${cfg.home}/data ${cfg.home}/store-apps </del> <ins> # create nextcloud directories. # if the directories exist already with wrong permissions, we fix that for dir in ${cfg.home}/config ${cfg.home}/data ${cfg.home}/store-apps; do if [ ! -e $dir ]; then install -o nextcloud -g nextcloud -d $dir elif [ $(stat -c "%G" $dir) != "nextcloud" ]; then chgrp -R nextcloud $dir fi done ln -sf ${overrideConfig} ${cfg.home}/config/override.config.php </ins> # Do not install if already installed if [[ ! -e ${cfg.home}/config/config.php ]]; then

${occSetTrustedDomainsCmd} ''; serviceConfig.Type = "oneshot"; <ins> serviceConfig.User = "nextcloud"; </ins> }; nextcloud-cron = { environment.NEXTCLOUD_CONFIG_DIR = "${cfg.home}/config";

services.phpfpm = { pools.nextcloud = { user = "nextcloud"; <del> group = "nginx"; </del> <ins> group = "nextcloud"; </ins> phpOptions = phpOptionsStr; phpPackage = phpPackage; phpEnv = {

PATH = "/run/wrappers/bin:/nix/var/nix/profiles/default/bin:/run/current-system/sw/bin:/usr/bin:/bin"; }; settings = mapAttrs (name: mkDefault) { <del> "listen.owner" = "nginx"; "listen.group" = "nginx"; </del> <ins> "listen.owner" = config.services.nginx.user; "listen.group" = config.services.nginx.group; </ins> } // cfg.poolSettings; extraConfig = cfg.poolConfig; }; }; <del> users.extraUsers.nextcloud = { </del> <ins> users.users.nextcloud = { </ins> home = "${cfg.home}"; <del> group = "nginx"; </del> <ins> group = "nextcloud"; </ins> createHome = true; }; <ins> users.groups.nextcloud.members = [ "nextcloud" config.services.nginx.user ]; </ins> environment.systemPackages = [ occ ]; <del> } (mkIf cfg.nginx.enable { services.nginx = { </del> <ins> services.nginx = mkDefault { </ins> enable = true; <del> virtualHosts = { ${cfg.hostName} = { root = cfg.package; locations = { "= /robots.txt" = { priority = 100; extraConfig = '' allow all; log_not_found off; access_log off; ''; }; "/" = { priority = 200; extraConfig = "rewrite ^ /index.php;"; }; "~ ^/store-apps" = { priority = 201; extraConfig = "root ${cfg.home};"; }; "= /.well-known/carddav" = { priority = 210; extraConfig = "return 301 $scheme://$host/remote.php/dav;"; }; "= /.well-known/caldav" = { priority = 210; extraConfig = "return 301 $scheme://$host/remote.php/dav;"; }; "~ ^/(?:build|tests|config|lib|3rdparty|templates|data)/" = { priority = 300; extraConfig = "deny all;"; }; "~ ^/(?:.|autotest|occ|issue|indie|db_|console)" = { priority = 300; extraConfig = "deny all;"; }; "~ ^/(?:index|remote|public|cron|core/ajax/update|status|ocs/v[12]|updater/.+|ocs-provider/.+|ocm-provider/.+).php(?:$|/)" = { priority = 500; extraConfig = '' include ${config.services.nginx.package}/conf/fastcgi.conf; fastcgi_split_path_info ^(.+.php)(/.*)$; try_files $fastcgi_script_name =404; fastcgi_param PATH_INFO $fastcgi_path_info; fastcgi_param HTTPS ${if cfg.https then "on" else "off"}; fastcgi_param modHeadersAvailable true; fastcgi_param front_controller_active true; fastcgi_pass unix:${fpm.socket}; fastcgi_intercept_errors on; fastcgi_request_buffering off; fastcgi_read_timeout 120s; ''; }; "~ ^/(?:updater|ocs-provider|ocm-provider)(?:$|/)".extraConfig = '' try_files $uri/ =404; index index.php; ''; "~ .(?:css|js|woff2?|svg|gif)$".extraConfig = '' try_files $uri /index.php$request_uri; add_header Cache-Control "public, max-age=15778463"; add_header X-Content-Type-Options nosniff; add_header X-XSS-Protection "1; mode=block"; add_header X-Robots-Tag none; add_header X-Download-Options noopen; add_header X-Permitted-Cross-Domain-Policies none; add_header X-Frame-Options sameorigin; add_header Referrer-Policy no-referrer; </del> <ins> virtualHosts.${cfg.hostName} = { root = cfg.package; locations = { "= /robots.txt" = { priority = 100; extraConfig = '' allow all; log_not_found off; </ins> access_log off; ''; <del> "~ .(?:png|html|ttf|ico|jpg|jpeg|bcmap|mp4|webm)$".extraConfig = '' try_files $uri /index.php$request_uri; access_log off; </del> <ins> }; "/" = { priority = 200; extraConfig = "rewrite ^ /index.php;"; }; "~ ^/store-apps" = { priority = 201; extraConfig = "root ${cfg.home};"; }; "= /.well-known/carddav" = { priority = 210; extraConfig = "return 301 $scheme://$host/remote.php/dav;"; }; "= /.well-known/caldav" = { priority = 210; extraConfig = "return 301 $scheme://$host/remote.php/dav;"; }; "~ ^/(?:build|tests|config|lib|3rdparty|templates|data)/" = { priority = 300; extraConfig = "deny all;"; }; "~ ^/(?:.|autotest|occ|issue|indie|db_|console)" = { priority = 300; extraConfig = "deny all;"; }; "~ ^/(?:index|remote|public|cron|core/ajax/update|status|ocs/v[12]|updater/.+|ocs-provider/.+|ocm-provider/.+).php(?:$|/)" = { priority = 500; extraConfig = '' include ${config.services.nginx.package}/conf/fastcgi.conf; fastcgi_split_path_info ^(.+.php)(/.*)$; try_files $fastcgi_script_name =404; fastcgi_param PATH_INFO $fastcgi_path_info; fastcgi_param HTTPS ${if cfg.https then "on" else "off"}; fastcgi_param modHeadersAvailable true; fastcgi_param front_controller_active true; fastcgi_pass unix:${fpm.socket}; fastcgi_intercept_errors on; fastcgi_request_buffering off; fastcgi_read_timeout 120s; </ins> ''; }; <del> extraConfig = '' </del> <ins> "~ ^/(?:updater|ocs-provider|ocm-provider)(?:$|/)".extraConfig = '' try_files $uri/ =404; index index.php; ''; "~ .(?:css|js|woff2?|svg|gif)$".extraConfig = '' try_files $uri /index.php$request_uri; add_header Cache-Control "public, max-age=15778463"; </ins> add_header X-Content-Type-Options nosniff; add_header X-XSS-Protection "1; mode=block"; add_header X-Robots-Tag none;

add_header X-Permitted-Cross-Domain-Policies none; add_header X-Frame-Options sameorigin; add_header Referrer-Policy no-referrer; <del> add_header Strict-Transport-Security "max-age=15552000; includeSubDomains" always; error_page 403 /core/templates/403.php; error_page 404 /core/templates/404.php; client_max_body_size ${cfg.maxUploadSize}; fastcgi_buffers 64 4K; fastcgi_hide_header X-Powered-By; gzip on; gzip_vary on; gzip_comp_level 4; gzip_min_length 256; gzip_proxied expired no-cache no-store private no_last_modified no_etag auth; gzip_types application/atom+xml application/javascript application/json application/ld+json application/manifest+json application/rss+xml application/vnd.geo+json application/vnd.ms-fontobject application/x-font-ttf application/x-web-app-manifest+json application/xhtml+xml application/xml font/opentype image/bmp image/svg+xml image/x-icon text/cache-manifest text/css text/plain text/vcard text/vnd.rim.location.xloc text/vtt text/x-component text/x-cross-domain-policy; ${optionalString cfg.webfinger '' rewrite ^/.well-known/host-meta /public.php?service=host-meta last; rewrite ^/.well-known/host-meta.json /public.php?service=host-meta-json last; ''} </del> <ins> access_log off; ''; "~ .(?:png|html|ttf|ico|jpg|jpeg|bcmap|mp4|webm)$".extraConfig = '' try_files $uri /index.php$request_uri; access_log off; </ins> ''; }; <ins> extraConfig = '' add_header X-Content-Type-Options nosniff; add_header X-XSS-Protection "1; mode=block"; add_header X-Robots-Tag none; add_header X-Download-Options noopen; add_header X-Permitted-Cross-Domain-Policies none; add_header X-Frame-Options sameorigin; add_header Referrer-Policy no-referrer; add_header Strict-Transport-Security "max-age=15552000; includeSubDomains" always; error_page 403 /core/templates/403.php; error_page 404 /core/templates/404.php; client_max_body_size ${cfg.maxUploadSize}; fastcgi_buffers 64 4K; fastcgi_hide_header X-Powered-By; gzip on; gzip_vary on; gzip_comp_level 4; gzip_min_length 256; gzip_proxied expired no-cache no-store private no_last_modified no_etag auth; gzip_types application/atom+xml application/javascript application/json application/ld+json application/manifest+json application/rss+xml application/vnd.geo+json application/vnd.ms-fontobject application/x-font-ttf application/x-web-app-manifest+json application/xhtml+xml application/xml font/opentype image/bmp image/svg+xml image/x-icon text/cache-manifest text/css text/plain text/vcard text/vnd.rim.location.xloc text/vtt text/x-component text/x-cross-domain-policy; ${optionalString cfg.webfinger '' rewrite ^/.well-known/host-meta /public.php?service=host-meta last; rewrite ^/.well-known/host-meta.json /public.php?service=host-meta-json last; ''} ''; </ins> }; }; <del> }) </del> <ins> } </ins> ]); meta.doc = ./nextcloud.xml;

services.nextcloud = { enable = true; <del> nginx.enable = true; </del> hostName = "nextcloud"; config = { # Don't inherit adminuser since "root" is supposed to be the default

services.nextcloud = { enable = true; hostName = "nextcloud"; <del> nginx.enable = true; </del> https = true; caching = { apcu = true;

services.nextcloud = { enable = true; hostName = "nextcloud"; <del> nginx.enable = true; </del> caching = { apcu = false; redis = true;