I figured it out, so I will give the detailed info to help people with the same problem already and for people that might run into this in the future, considering how many questions and issues I found about this without answers.
The Issue was the FPM root location in the FastCGI Parameters of the NGinX conf file
So I was on the right track, and the problem was tied to the root directive.
After much reading I stumbled upon this post:
How to correctly link php-fpm and Nginx Docker containers?
And suddenly it became clear I had two different services reading 2 different paths, and one was feeding the root path of the other one where it didn't exist.
Remember I had mounted the www volume to be shared between the 2 containers?
- For the NGinX Container on
www:/usr/share/nginx/html
- For the NextCloud FPM Container on
www:/var/html/www
The idea behind this was for the two containers to share the filesystem of the NextCloud app.
What I didn't realize is that in this deployment, NGinX's purpose is to serve the static files, like CSS, HTML, JPG, JS, etc., while routing PHP calls to the NextCloud FPM container with the FastCGI Parameters.
When the root directive in the NGinX conf file is declared, it gets set as the variable $document_root
.
root /usr/share/nginx/html;
So when setting the root to the path on the NGinX Container /usr/share/nginx/html
this works to serve the static files without issues, but then, when a PHP call is made it's fed to the php-hanlder in the NextCloud FPM Container, since that location doesn't exist inside the second container, it can't find the PHP file.
To fix this I searched for the block with the FastCGI Parameters and searched for the $document_root
variable, found it, and looks like this:
location ~ \.php(?:$|/) {
# Required for legacy support
rewrite ^/(?!index|remote|public|cron|core\/ajax\/update|status|ocs\/v[12]|updater\/.+|oc[ms]-provider\/.+|.+\/richdocumentscode\/proxy) /index.php$request_uri;
fastcgi_split_path_info ^(.+?\.php)(/.*)$;
set $path_info $fastcgi_path_info;
try_files $fastcgi_script_name =404;
include fastcgi_params;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
fastcgi_param PATH_INFO $path_info;
#fastcgi_param HTTPS on;
fastcgi_param modHeadersAvailable true; # Avoid sending the security headers twice
fastcgi_param front_controller_active true; # Enable pretty urls
fastcgi_pass php-handler;
fastcgi_intercept_errors on;
fastcgi_request_buffering off;
}
Note how the line that says fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
is forming the Script Path with the root already declared, so when processing nextcloud.example.com
it tries to read index.php
and this is the resulting call to the NextCloud FPM container:
/usr/share/nginx/html/index.php
The correct call would have been:
/var/www/html/index.php
So I created a new variable named $fpm_root
and set it to /var/www/html/
, then changed the line that says fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
to fastcgi_param SCRIPT_FILENAME $fpm_root$fastcgi_script_name;
Now whenever it gets a call for static content it will resolve NGinX's Container path and when it gets a call for PHP content the NextCloud FPM's Container path.
Here's how the whole section looks now:
location ~ \.php(?:$|/) {
# Required for legacy support
rewrite ^/(?!index|remote|public|cron|core\/ajax\/update|status|ocs\/v[12]|updater\/.+|oc[ms]-provider\/.+|.+\/richdocumentscode\/proxy) /index.php$request_uri;
fastcgi_split_path_info ^(.+?\.php)(/.*)$;
set $path_info $fastcgi_path_info;
set $fpm_root /var/www/html/;
try_files $fastcgi_script_name =404;
include fastcgi_params;
fastcgi_param SCRIPT_FILENAME $fpm_root$fastcgi_script_name;
fastcgi_param PATH_INFO $path_info;
fastcgi_param HTTPS on;
fastcgi_param modHeadersAvailable true; # Avoid sending the security headers twice
fastcgi_param front_controller_active true; # Enable pretty urls
fastcgi_pass php-handler;
fastcgi_intercept_errors on;
fastcgi_request_buffering off;
}
It works now and passes all the internal NextCloud health and security checks once I added the line:
add_header Strict-Transport-Security "max-age=31536000; includeSubDomains" always;
Conclusion
And I hope this helps anyone searching for this issue, the problem was that I had two different paths for the services processing both types of content, static and PHP, and only one of them was properly set on the NGinX conf file.
You can have two different (or more) root locations for a dockerized FPM deployment, and this could probably do to work or deploy static content into two or more different apps using the same FPM container to handle PHP calls for NextCloud, WordPress, PHPPGAdmin, Laravel or whatever you are working on.