detfalskested

Nextcloud run as PHP-FPM in Docker, served via external nginx

As part of moving all my self hosted stuff to a new home server, I'm switching from serving Nextcloud directly from the host machine, to have it run in a Docker container.

I just managed to solve a problem with running Nextcloud from their nextcloud:fpm Docker image that I have been battling for a few days.

The fpm version of the container image is supposed to be accessed behind a web server like nginx. The web server is required in order to serve static files and other non-PHP content. Their examples suggest setting up a Docker compose file that runs both the fpm container and an nginx container. But I already have nginx running somewhere else and don't want to have multiple of those running.

The Nextcloud documentation provides an example configuration for nginx to use as a starting point.

Despite (roughly) following their guide for nextcloud:fpm, I kept getting a 404 response with the following body:

File not found.

Searching for this in the Nextcloud source led me on a detour: The string "File not found." is found in a file called apps/files/lib/Controller/ApiController.php, which made me believe this is where the response came from. But it turned out not to be the case and I scratched my head for a while, as I didn't see any changes when I altered that file. As I understand it, this specific response is instead (or also) a default response from the php-fpm process if it cannot find the file to process, and my best guess is that Nextcloud mimics this as a sort of security by obscurity when it doesn't know how to handle a request.

According to the nextcloud:fpm documentation, the web root should be mounted as a volume. Let's say these files are supposed to reside on your host in /path/to/nextcloud/data/www. Then your compose file should have a volume defined as:

...
  volumes:
  - /path/to/nextcloud/data/www:/var/www/html
...

If you ran nginx as part of the compose setup as suggested in their documentation, that container would have an identical mount, and nginx would serve files from /var/www/html.

But as I have an external nginx, it does not simply have /var/www/html set as the root for the Nextcloud virtual host. Instead, its root is set to be /path/to/nextcloud/data/www. And this is where the problem is: This absolute path is passed on to the upstream fpm handler, running in the Docker container, and this path does not exist in the container, which results in the "File not found." response.

My solution is to add another volume in the compose file, that also mounts the web root at the same location inside the container (having it mounted twice):

...
  volumes:
  - /path/to/nextcloud/data/www:/var/www/html
  - /path/to/nextcloud/data/www:/path/to/nextcloud/data/www
...

This makes sure that both nginx on the host and php-fpm in the container can find the PHP files in the same place.