Nginx and accessing the root domain ("/")

I’ve nginx setup like this:

services.nginx = {
    enable = true;
    virtualHosts."domain1.com" = {
      enableACME = true;
      forceSSL = true;
      root = domain1-source.source-code;
      locations."~ \.php$".extraConfig = ''
        fastcgi_pass  unix:${config.services.phpfpm.pools.${domain1_app}.socket};
        fastcgi_index index.php;
        include ${pkgs.nginx}/conf/fastcgi_params;
        include ${pkgs.nginx}/conf/fastcgi.conf;
      '';
    };
    virtualHosts."domain2.com" = {
      enableACME = true;
      forceSSL = true;
      root = domain2-source-code;
      locations."~ \.php$".extraConfig = ''
        fastcgi_pass  unix:${config.services.phpfpm.pools.${domain2_app}.socket};
        fastcgi_index index.php;
        include ${pkgs.nginx}/conf/fastcgi_params;
        include ${pkgs.nginx}/conf/fastcgi.conf;
      '';
    };
  };

When I do like the above, with locations."~ \.php$".extraConfig, then I’m able to access domain1.com/index.php, but at domain1.com/ I get an nginx 403 Forbidden.

If I change to locations."/".extraConfig, then I’m able to access domain1.com/ (it takes me to domain1.com/index.php), but then I’m getting a lot of weird issues with accessing resources. Example log entries (journalctl -u nginx):

Aug 28 18:07:09 myvps nginx[414979]: 2021/08/28 18:07:09 [error] 414979#414979: *17 FastCGI sent in stderr: "Access to the
 script '/nix/store/a4vd9y0rz57sdg3vy2hi004fpyhjgh54-domain1-source/js/register.js' has been denied (see security.limit_extensions)" while re
ading response header from upstream, client: some_ip, server: domain1.com, request: "GET /js/register.js HTTP/2.0", upstream: "fastc
gi://unix:/run/phpfpm/domain1_app.sock:", host: "domain1.com", referrer: "https://domain1.com/login.php?"

It looks like PHP is then not able to access the resources I’m referring to, like .js and .css files. This problem is not present with locations."~ \.php$".extraConfig, which probably makes sense to someone more knowledgeable about this than me. Anyone able to spot my mistake? Thanks!

To put it simple, you want that an access to the root / really forwards to /index.php? Because I’m no PHP expert, but even my installation of Nextcloud that indeed uses fastcgi and phpfpm has this in the final configuration:

location / {
    rewrite ^ /index.php;
}

Which maybe what are you lacking?

Thanks for responding, @azazel75 ! I tried adding that now, like this:

      locations."~ \.php$".extraConfig = ''
        try_files $uri =404;
        fastcgi_pass  unix:${config.services.phpfpm.pools.${domain1_app}.socket};
        fastcgi_index index.php;
        include ${pkgs.nginx}/conf/fastcgi_params;
        include ${pkgs.nginx}/conf/fastcgi.conf;
      '';
      locations."/".extraConfig = ''
        rewrite ^ /index.php;
      '';

But that gets me the same issue that I mentioned above: I am indeed redirected from / to index.php, but it’s not able to pull in images, css, or js files.

Sorry, I was a bit lazy before, but it seems to me that you lack a correct setting of the root of your sites in order to serve files like /js/register.js in the error print above or else some proxying of the same resources into fastcgi/ phpfpm to let it serve them. So for example something like this or that or both :wink:

Thanks for those links! If you look at the code in the original post, I do set the root (e.g. root = domain1-source-code;). And when I use locations."~ \.php$".extraConfig and then to go domain1.com/index.php, everything seems to work (js, css, images). Is there then something in the "~ \.php$" that I’m failing to understand? Does "~ \.php$" somehow mean "allow php files and also allow everything else (js, css, images), but do not accept visitors going to domain1.com/ ? I’m a little confused.

I tried this now:

      locations = {
          "~ \.php$" = {
              priority = 100;
              extraConfig = ''
                try_files $uri =404;
                fastcgi_pass  unix:${config.services.phpfpm.pools.${domain1_app}.socket};
                fastcgi_index index.php;
                include ${pkgs.nginx}/conf/fastcgi_params;
                include ${pkgs.nginx}/conf/fastcgi.conf;
              '';
          };
          "/" = {
              priority = 200;
              extraConfig = ''
                rewrite ^ /index.php;
              '';
          };
      };

Hoping that the priority would make the "/" location only kick in when I go to the root domain, and then having the other "~ \.php$" location kick in for everything else, but it didn’t work. Going to / does redirect me to index.php, but no images, css, or js.

This works:

      locations = {
          "= /" = {
              extraConfig = ''
                rewrite ^ /index.php;
              '';
          };
          "~ \.php$" = {
              extraConfig = ''
                try_files $uri =404;
                fastcgi_pass  unix:${config.services.phpfpm.pools.${domain1_app}.socket};
                fastcgi_index index.php;
                include ${pkgs.nginx}/conf/fastcgi_params;
                include ${pkgs.nginx}/conf/fastcgi.conf;
              '';
          };
      };

My mistake was having "/", which is a kind of catch-all, instead of "= /", which matches only the root. Thanks for the pointers and the links :slight_smile:

2 Likes