Home » Php » How to resolve a PHP-FPM Primary script unknown with a PHP-FPM and an Nginx Docker container?

How to resolve a PHP-FPM Primary script unknown with a PHP-FPM and an Nginx Docker container?

Posted by: admin July 12, 2020 Leave a comment

Questions:

My situation is this, I have two Docker containers:

  1. Runs PHP-FPM on port 9000
  2. Runs nginx and has PHP files (should the PHP-FPM container have access to the files?)

I keep getting the following error:

FastCGI sent in stderr: "Primary script unknown" while reading response header from upstream, client: 172.17.0.1, ser
ver: _, request: "GET / HTTP/1.1", upstream: "fastcgi://172.17.0.2:9000", host: "172.17.0.3"

I read here that this is “always related to a wrongly set SCRIPT_FILENAME in the nginx fastcgi_param directive.”

The problem is, I don’t know how to resolve it 😛

Config in Container 2:

server {
    listen 80 default_server;
    listen [::]:80 default_server;

    charset UTF-8;
    root /var/www/WordPress;

    index index.php index.html index.htm;
    server_name _;
    location / {
        try_files $uri/ /index.php?$args;
    }
    location ~ \.php$ {
        try_files $uri =404;
        fastcgi_split_path_info ^(.+\.php)(/.+)$;
        fastcgi_index index.php;
        fastcgi_pass 172.17.0.2:9000;
        include fastcgi_params;
        fastcgi_param SCRIPT_FILENAME /var/www/WordPress$fastcgi_script_name;
        # set headers
        add_header Cache-Control $cc;
        access_log off;
        expires $ex;
    }
    location ~* \.(js|css|svg|png|jpg|jpeg|gif|ico|eot|otf|ttf|woff)$ {
        add_header Access-Control-Allow-Origin *;
        add_header Cache-Control "public";
        access_log off;
        log_not_found off;
        expires 1y;
    }
    location ~ /\.ht {
           deny all;
    }
}
How to&Answers:

Change root line to: root /var/www/WordPress/; for the $fastcgi_script_name doesn’t include /

Answer:

I’m no nginx expert, but literally every instance of fastcgi_param SCRIPT_FILENAME in the docs ends with $fastcgi_script_name, and yours doesn’t.

Answer:

I broke my brain trying to figure out why it is not working.
As usual, it’s a matter of inattention.
So, in my nginx.conf I have lines:

set $root "/var/www/html/web";

root   $root;
set $bootstrap "index.php";
index  $bootstrap;

location / {
    index  index.html $bootstrap;
    try_files $uri $uri/ /$bootstrap?$args;
    expires    -1;
}

location ~ \.php$ {
    fastcgi_split_path_info  ^(.+.php)(.*)$;

    set $fsn /$bootstrap;
    if (-f $document_root$fastcgi_script_name) {
        set $fsn $fastcgi_script_name;
    }

    fastcgi_pass php:9000;
    fastcgi_index $bootstrap;
    include fastcgi_params;

    fastcgi_param  SCRIPT_FILENAME  $document_root$fsn;

    fastcgi_param  PATH_INFO        $fastcgi_path_info;
    fastcgi_param  PATH_TRANSLATED  $document_root$fsn;

    try_files $fsn =404;
    expires    -1;
}

include defaults.conf;

Very important to pay attention to line if (-f $document_root$fastcgi_script_name) {, because it is a check for existence.
In my docker-compose.yml I had different mounts in the nginx-container and the php-container:

php:
  image: aspendigital/octobercms:php7.2-fpm
  container_name: "${PROJECT_NAME}_php"
  volumes:
    - ./web:/var/www/html # <- this line is incorrect! Mounts MUST be identical! 
nginx:
  image: wodby/nginx:$NGINX_TAG
  container_name: "${PROJECT_NAME}_nginx"
  depends_on:
    - php
  environment:
    NGINX_STATIC_OPEN_FILE_CACHE: "off"
    NGINX_ERROR_LOG_LEVEL: debug
    NGINX_BACKEND_HOST: php
    NGINX_SERVER_ROOT: /var/www/html/web/
    NGINX_CONF_INCLUDE: /var/www/html/nginx/*.conf
  volumes:
    - ./:/var/www/html:cached

So, replaсing in php-part the volume to the same as in the nginx-part solved my problem.
Be careful!