Nextcloud:FPM - Primary script unknown


I’m trying to install nextcloud:fpm and I can’t realise what I’m doing wrong.

Here’s my setup:

  • MariaDB 10.5: external DB (
  • Local (host) NGINX, non-Dokerized
  • NextCloud: nextcloud:fpm installed in /docker/nextcloud/files , FPM port should be 10001

Please note that I don’t want to use Docker Volumes (/docker is on SSD while / is on HDD), so the local NGINX should be physically pointed to NextCloud’s docker files.

The error that I’m receiving is: [error] 7191#7191: 1 FastCGI sent in stderr: “Primary script unknown” while reading response header from upstream, client:, server: cloud.hostname.tld, request: “GET / HTTP/2.0”, upstream: “fastcgi://”, host: "cloud.hostname.tld"

Any help is really appreciated as I’m really stuck with this.

Here’s docker-compose.yml:

version: '2'

    image: nextcloud:fpm
    restart: unless-stopped
      - "10001:9000"
      - /docker/nextcloud/files:/var/www/html

Here’s NGINX’s nextcloud.conf:

upstream php-handler {

server {
    listen 80;
    listen [::]:80;
    server_name cloud.hostname.tld;
    return 301 https://$server_name$request_uri;

server {
    listen 443 ssl http2;
    server_name cloud.hostname.tld;

    ssl_certificate /etc/letsencrypt/live/cloud.hostname.tld/fullchain.pem;
    ssl_certificate_key /etc/letsencrypt/live/cloud.hostname.tld/privkey.pem;

    add_header Strict-Transport-Security "max-age=15768000; includeSubDomains; preload;" always;

    client_max_body_size 5G;
    fastcgi_buffers 64 4K;

    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/ 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;

    add_header Referrer-Policy                      "no-referrer"   always;
    add_header X-Content-Type-Options               "nosniff"       always;
    add_header X-Download-Options                   "noopen"        always;
    add_header X-Frame-Options                      "SAMEORIGIN"    always;
    add_header X-Permitted-Cross-Domain-Policies    "none"          always;
    add_header X-Robots-Tag                         "none"          always;
    add_header X-XSS-Protection                     "1; mode=block" always;

    fastcgi_hide_header X-Powered-By;

    root /docker/nextcloud/files;

    index index.php index.html /index.php$request_uri;

    location = / {
        if ( $http_user_agent ~ ^DavClnt ) {
            return 302 /remote.php/webdav/$is_args$args;

    location = /robots.txt {
        allow all;
        log_not_found off;
        access_log off;

    location ^~ /.well-known {
        location = /.well-known/carddav { return 301 /remote.php/dav/; }
        location = /.well-known/caldav  { return 301 /remote.php/dav/; }
        location /.well-known/acme-challenge    { try_files $uri $uri/ =404; }
        location /.well-known/pki-validation    { try_files $uri $uri/ =404; }
        return 301 /index.php$request_uri;

    location ~ ^/(?:build|tests|config|lib|3rdparty|templates|data)(?:$|/)  { return 404; }
    location ~ ^/(?:\.|autotest|occ|issue|indie|db_|console)                { return 404; }
    location ~ \.php(?:$|/) {
        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;

    location ~ \.(?:css|js|svg|gif|png|jpg|ico)$ {
        try_files $uri /index.php$request_uri;
        expires 6M;         # Cache-Control policy borrowed from `.htaccess`
        access_log off;     # Optional: Don't log access to assets

    location ~ \.woff2?$ {
        try_files $uri /index.php$request_uri;
        expires 7d;         # Cache-Control policy borrowed from `.htaccess`
        access_log off;     # Optional: Don't log access to assets

    location /remote {
        return 301 /remote.php$request_uri;

    location / {
        try_files $uri $uri/ /index.php$request_uri;

Thank you!

Hey, I just ran into a similar problem with nginx on the local host and couldn’t figure out what’s wrong. The problem most likely is the different path to the files in the docker container and on the host. In the php block of the nginx config $document_root points to /docker/nextcloud/files while php-fpm in the container can’t access this as this path doesn’t exist. There the path is /var/www/html. In my case replacing $document_root with the path in the nextcloud container, /var/www/html, solved this issue. There is probabaly a better solution to this.
I hope this helps or points in the right direction.

Isn’t $document_root replaced at the first Docker update?

It shouldn’t. As I understood it you use nginx on your host without Docker. I don’t know how you manage your nginx config, but unless the nextcloud.conf is somehow connected to your nextcloud:fpm container, the config shouldn’t change. Updating the container with Docker should only affect the fpm server running in the container, your host nginx just passes requests to it.

So basically you stored NextCloud’s docker files in the hosts’s /var/www/html? That is kinda impossible in my scenario.

No, I mean the nextcloud.conf you posted, the configuration for your host’s nginx server. The $document_root within the php block needs to match the path of the files in the Docker container. Otherwise the path to the file passed to the fpm server running in Docker can’t find the file, hence the error “Primary script unknown”.

In docker-compose.yml you map the directory /var/www/html to /docker/nextcloud/files. In the config for nginx you specify the mapped directory, root /docker/nextcloud/files;. So nginx passes the mapped path to fpm running in the container, but that path doesn’t exist there.

Ok, so in this scenario what would be the solution? Physically keep files in the host’s /var/www/html? Thank you for taking your time for this!

The solution would be exactly what I wrote. You don’t need /var/www/html on your host. You wrote you use nginx on your host, no docker. You tell nginx to pass php files to fpm in the nextcloud container, a different environment. For your host’s nginx the files reside in /docker/nextcloud/files which is fine. But php-fpm in the container doesn’t know this path. It only knows of /var/www/html within the container. So you have to tell fpm where to look for the files. With the information and config you posted initially only changing a single line will fix the issue, replacing the variable $document_root (which points to /docker/nextcloud/files) with the path in the container so that fpm actually finds the file. So if you write fastcgi_param SCRIPT_FILENAME /var/www/html/$fastcgi_script_name; in your host’s nginx config which shouldn’t be affected by any docker-related stuff php-fpm in your nextcloud container can find the file then and the error that it can’t find the script should be gone.