Change:
I've worked around with some manual setup, which I think is OK / not causing this issue. After that, any attempt to access the piwik virtual host results in a bad gateway error. The logs for nginx show a permission error of some kind: Enable the piwik module and try to connect to the virtual host. Let me know if I've mangled something / if you want me to try things - I'm keen to get this running. System: NixOS 17.03.1606. (Gorilla) Nix version: nix-env (Nix) 1.11.11 Nixpkgs versions: nixpkgs:"17.03.1606." unstable:"17.09pre111304." Sandboxing enabled: build-use-sandbox = false
cc
This sounds like phpfpm had problems starting up. Does exist? What does say? What does say?
The socket exists: The service is running: The setup service ran, but is not still running: There is one thing I did remember over the weekend that might be relevant. I'm running this in NixOps to test it out before I start playing around on our main server, so I've turned off the various SSL / ACME options.
Could you post your piwik / nginx nixos config, please? The socket should be owned by nginx, not by piwik. Could it be that you set to , instead of leaving the default?
That would probably be it. I didn't set a user initially, but got an error about webServerUser being unknown. After that I got lazy and used the piwik user rather than reading the module. I'll retrace my steps when I get to work tomorrow and see how things go with the nginx user / try to figure out why the default wasn't working for me.
It looks like has an example but not a default. I can address that in a PR if that is helpful.
Right, I forgot I removed the when I made the nginx option null by default. I'll try to see whether I can make nginx the default for only in case the nginx option is not null somehow, and see whether I can improve the error to something better than is unknown. Also, while “Name of the owner of the {phpSocket} fastcgi socket for piwik. The user is granted access on ${phpSocket}.“ or something like that. Do you think that would clear things up?
That change to the docs would definitely clear things up - although I really should have read the module :) I've got a potential fix for the default along with the doc change you suggested. I'm not really set up to test NixOS changes at the moment though, but if it looks good to you I can try to find a way. It all seems to be working well now - thanks for your help!
While it's always a good idea, I still want to strive for a module that doesn't require that. I don't think will still fail at build time, right? But that's definitely something I want to keep, to stop it from failing at runtime. php-fpm's startup will fail if no webServerUser is set. I think we should not add a default here, but look into whether we can either use something like = ${cfg.webServerUser}` part. Additionally, we should state in the docs of the webServerUser option that it's mandatory if nginx attribute is not used, and in the enable option that either webServerUser or nginx option is mandatory. It was shown to me that documenting the fact it's mandatory + no default is the way other modules handle this situation as well. Do you want to work on this? Alternatively, I think I can take care of this the day after tomorrow.
I probably won't have time to work on this (at least not in the near term) - but I can probably do something dodgy to test changes out via my NixOps setup if that helps.
My PR at includes a fix for this.

Discussion:
You can safely ignore this, unless you need a plugin that needs JavaScript tracker access. </para> </listitem> <del> <listitem> <para> Sending mail from piwik, e.g. for the password reset function, might not work out of the box: There's a problem with using <command>sendmail</command> from <literal>php-fpm</literal> that is being investigated at <link xlink:href="https://github.com/NixOS/nixpkgs/issues/26611" />. If you have (or don't have) this problem as well, please report it. You can enable SMTP as method to send mail in piwik's <quote>General Settings</quote> > <quote>Mail Server Settings</quote> instead. </para> </listitem> </del> </itemizedlist> </section>

default = false; description = '' Enable piwik web analytics with php-fpm backend. <ins> Either the nginx option or the webServerUser option is mandatory. </ins> ''; }; webServerUser = mkOption { <del> type = types.str; example = "nginx"; </del> <ins> type = types.nullOr types.str; default = null; example = "lighttpd"; </ins> description = '' <del> Name of the owner of the ${phpSocket} fastcgi socket for piwik. </del> <ins> Name of the web server user that forwards requests to the ${phpSocket} fastcgi socket for piwik if the nginx option is not used. Either this option or the nginx option is mandatory. </ins> If you want to use another webserver than nginx, you need to set this to that server's user and pass fastcgi requests to `index.php` and `piwik.php` to this socket. '';

}; nginx = mkOption { <del> # TODO: for maximum flexibility, it would be nice to use nginx's vhost_options module #       but this only makes sense if we can somehow specify defaults suitable for piwik. #       But users can always copy the piwik nginx config to their configuration.nix and customize it. type = types.nullOr (types.submodule { options = { virtualHost = mkOption { type = types.str; default = "piwik.${config.networking.hostName}"; example = "piwik.${config.networking.hostName}"; description = '' Name of the nginx virtualhost to use and set up. ''; }; enableSSL = mkOption { type = types.bool; default = true; description = "Whether to enable https."; }; forceSSL = mkOption { type = types.bool; default = true; description = "Whether to always redirect to https."; }; enableACME = mkOption { type = types.bool; default = true; description = "Whether to ask Let's Encrypt to sign a certificate for this vhost."; }; }; }); </del> <ins> type = types.nullOr (types.submodule (import ../web-servers/nginx/vhost-options.nix { inherit config lib; })); </ins> default = null; <del> example = { virtualHost = "stats.${config.networking.hostName}"; }; </del> <ins> example = { serverName = "stats.${config.networking.hostName}"; enableACME = false; }; </ins> description = '' <del> The options to use to configure an nginx virtualHost. If null (the default), no nginx virtualHost will be configured. </del> <ins> With this option, you can customize an nginx virtualHost which already has sensible defaults for piwik. Either this option or the webServerUser option is mandatory. Set this to {} to just enable the virtualHost if you don't need any customization. If enabled, then by default, the serverName is piwik.${config.networking.hostName}, SSL is active, and certificates are acquired via ACME. If this is set to null (the default), no nginx virtualHost will be configured. </ins> ''; }; }; }; config = mkIf cfg.enable { <ins> warnings = mkIf (cfg.nginx != null && cfg.webServerUser != null) [ "If services.piwik.nginx is set, services.piwik.nginx.webServerUser is ignored and should be removed." ]; assertions = [ { assertion = cfg.nginx != null || cfg.webServerUser != null; message = "Either services.piwik.nginx or services.piwik.nginx.webServerUser is mandatory"; }]; </ins> users.extraUsers.${user} = { isSystemUser = true;

serviceConfig.UMask = "0007"; }; <del> services.phpfpm.poolConfigs = { </del> <ins> services.phpfpm.poolConfigs = let # workaround for when both are null and need to generate a string, # which is illegal, but as assertions apparently are being triggered *after* config generation, # we have to avoid already throwing errors at this previous stage. socketOwner = if (cfg.nginx != null) then config.services.nginx.user else if (cfg.webServerUser != null) then cfg.webServerUser else ""; in { </ins> ${pool} = '' listen = "${phpSocket}" <del> listen.owner = ${cfg.webServerUser} </del> <ins> listen.owner = ${socketOwner} </ins> listen.group = root listen.mode = 0600 user = ${user}

# References: # https://fralef.me/piwik-hardening-with-nginx-and-php-fpm.html # https://github.com/perusio/piwik-nginx <del> ${cfg.nginx.virtualHost} = { root = "${pkgs.piwik}/share"; enableSSL  = cfg.nginx.enableSSL; enableACME = cfg.nginx.enableACME; forceSSL   = cfg.nginx.forceSSL; </del> <ins> "${user}.${config.networking.hostName}" = mkMerge [ cfg.nginx { # don't allow to override root, as it will almost certainly break piwik root = mkForce "${pkgs.piwik}/share"; # allow to override SSL settings if necessary, i.e. when using another method than ACME # but enable them by default, as sensitive login and piwik data should not be transmitted in clear text. forceSSL = mkDefault true; enableACME = mkDefault true; </ins> locations."/" = { index = "index.php";

locations."= /piwik.js".extraConfig = '' expires 1M; ''; <del> }; </del> <ins> }]; </ins> }; };