TransWikia.com

Nginx (Ubuntu 18.04) FastCGI sent in stderr: "Primary script unknown" while reading response header from upstream

Server Fault Asked by 0LEg on December 9, 2021

Well… I know there are so many simular questions asked. But in order to make this post to be somehow userful for community once being solved I would like to list up a working Nginx + PHP-fpm conf files for WordPress. But as of now It dosn’t work, he he.

As that is my second time dealing with Nginx (fisrt set up was with close to default settings) configuration I’m afraid I can not handle troubleshouting wihtout help.
What I’m tring to do is to set up Nginx with FastCGI cache in order to kick WordPress’ butt to make it run faster.
Right after install nginx was able to show default greeting html page while adressing http://vps_ip_adress. I guess that means networking and basic set up is fine.
Then I installed php7.4-fpm and tune a bit nginx configuration to enable FastCGI cache for futher WordPress install. For testing purpose I put info.php file containing <?php phpinfo(); ?> into sire root dir /var/www/html/mysitename/info.php.
Now I’m getting FastCGI sent in stderr: "Primary script unknown" while reading response header from upstream in nginx error log. I already read that it means php-fpm can not locate scripit, most likely due to wrong scrip name somthere in nginx configuration. Unfortunately being not expirienced with nginx I can not locate the error.

As a reference I used nginx configuration found on internet (yeah… I know, problem with stuff found in internet – it never work he he). In case if with someonce’s help I’ll get it working here will be listed Nginx+PHP-fpm set up with FAstCGI cache which is quite demanded I guess. Any advices of how to iptimize nginx+php-fpm configuration for WordPress wil be much appreciated.

~~~~~~~Configuration listings~~~~~~~

/etc/nginx/nginx.conf

user www-data;
worker_processes 2;
pid /run/nginx.pid;
include /etc/nginx/modules-enabled/*.conf;

events {
        worker_connections 768;
        multi_accept on;
}

http {

        #FastCGI cache settings
        fastcgi_cache_path /etc/nginx/cache levels=1:2 keys_zone=WORDPRESS:100m max_size=4g inactive=60m use_temp_path=off;
        fastcgi_cache_key "$scheme$request_method$host$request_uri";
        #
        fastcgi_buffers 8 16k;
        fastcgi_buffer_size 32k;
        fastcgi_connect_timeout 300;
        fastcgi_send_timeout 300;
        fastcgi_read_timeout 300;
        ##
        # Basic Settings
        ##

        sendfile on;
        tcp_nopush on;
        tcp_nodelay on;
        keepalive_timeout 15;
        types_hash_max_size 2048;
        server_tokens off;
        client_max_body_size 64m;
        # server_names_hash_bucket_size 64;
        # server_name_in_redirect off;

        include /etc/nginx/mime.types;
        default_type application/octet-stream;

        ##
        # SSL Settings
        ##

        ssl_protocols TLSv1 TLSv1.1 TLSv1.2; # Dropping SSLv3, ref: POODLE
        ssl_prefer_server_ciphers on;

        ##
        # Logging Settings
        ##

        access_log /var/log/nginx/access.log;
        error_log /var/log/nginx/error.log;

        ##
        # Gzip Settings
        ##

        gzip on;

        # gzip_vary on;
        gzip_proxied any;
        gzip_comp_level 2;
        # gzip_buffers 16 8k;
        # gzip_http_version 1.1;
        gzip_types text/plain text/css application/json application/javascript text/xml application/xml application/xml+rss text/javascript;

        ##
        # Virtual Host Configs
        ##

        include /etc/nginx/conf.d/*.conf;
        include /etc/nginx/sites-enabled/*;

        server {
                listen 80 default_server;
                listen [::]:80 default_server;
                server_name _;
                return 444;
               }

}

/etc/nginx/fastcgi.conf

fastcgi_param  SCRIPT_FILENAME    $document_root$fastcgi_script_name;
fastcgi_param  QUERY_STRING       $query_string;
fastcgi_param  REQUEST_METHOD     $request_method;
fastcgi_param  CONTENT_TYPE       $content_type;
fastcgi_param  CONTENT_LENGTH     $content_length;

fastcgi_param  SCRIPT_NAME        $fastcgi_script_name;
fastcgi_param  REQUEST_URI        $request_uri;
fastcgi_param  DOCUMENT_URI       $document_uri;
fastcgi_param  DOCUMENT_ROOT      $document_root;
fastcgi_param  SERVER_PROTOCOL    $server_protocol;
fastcgi_param  REQUEST_SCHEME     $scheme;
fastcgi_param  HTTPS              $https if_not_empty;

fastcgi_param  GATEWAY_INTERFACE  CGI/1.1;
fastcgi_param  SERVER_SOFTWARE    nginx/$nginx_version;

fastcgi_param  REMOTE_ADDR        $remote_addr;
fastcgi_param  REMOTE_PORT        $remote_port;
fastcgi_param  SERVER_ADDR        $server_addr;
fastcgi_param  SERVER_PORT        $server_port;
fastcgi_param  SERVER_NAME        $server_name;

# PHP only, required if PHP was built with --enable-force-cgi-redirect
fastcgi_param  REDIRECT_STATUS    200;

/etc/nginx/site-enabled/mysitename.conf

server {
        # As DNS records are not well set up, I'm suing IP adress. To be replaced with domain name 
        server_name xxx.xxx.xxx.xxx;

        access_log   /var/log/nginx/mysitename.access.log;
        error_log    /var/log/nginx/mysitename.error.log;

        root /var/www/mysitename;
        index index.php;
#
        set $skip_cache 0;
#

        # POST requests and urls with a query string should always go to PHP
        if ($request_method = POST) {
                set $skip_cache 1;
        }
        if ($query_string != "") {
                set $skip_cache 1;
        }

        # Don't cache uris containing the following segments
        if ($request_uri ~* "/wp-admin/|/xmlrpc.php|wp-.*.php|/feed/|index.php|sitemap(_index)?.xml") {
                set $skip_cache 1;
        }

        # Don't use the cache for logged in users or recent commenters
        if ($http_cookie ~* "comment_author|wordpress_[a-f0-9]+|wp-postpass|wordpress_no_cache|wordpress_logged_in") {
                set $skip_cache 1;
        }

        #Don't chache for store, cart,my account, checkout pages
        if ($request_uri ~* "/store.*|/cart.*|/my-account.*|/checkout.*|/addons.*") {
         set $skip_cache 1;
        }

        #Skip cache for WooCommerce query string
        if ( $arg_add-to-cart != "" ) {
          set $skip_cache 1;
        }


        location / {
                try_files $uri $uri/ /index.php?$args;
        }

        location ~ .php$ {

                          fastcgi_split_path_info ^(.+.php)(/.+)$;
                          fastcgi_pass 127.0.0.1:9000;
                          fastcgi_index index.php;
                          include fastcgi_params;

                          set $rt_session "";

        if ($http_cookie ~* "wc_session_cookie_[^=]*=([^%]+)%7C") {
                    set $rt_session wc_session_cookie_$1;
            }

        if ($skip_cache = 0 ) {
            more_clear_headers "Set-Cookie*";
            set $rt_session "";
            }

            fastcgi_cache_key "$scheme$request_method$host$request_uri$rt_session";

            fastcgi_cache WORDPRESS;
            fastcgi_cache_valid 200 301 302 60m;
            fastcgi_cache_use_stale error timeout updating invalid_header http_500 http_503;
            fastcgi_cache_min_uses 1;
            fastcgi_cache_lock on;
            add_header X-FastCGI-Cache $upstream_cache_status;
            fastcgi_cache_bypass $http_cookie $cookie_nocache $skip_cache;
            fastcgi_no_cache $http_cookie ~* "comment_author_|wordpress_(?!test_cookie)|wp-postpass_" $skip_cache;

            fastcgi_cache_background_update on;

        }

        location ~ /purge(/.*) {
            fastcgi_cache_purge WORDPRESS "$scheme$request_method$host$1";
        }

        location ~* ^.+.(ogg|ogv|svg|svgz|eot|otf|woff|mp4|ttf|rss|atom|jpg|jpeg|gif|png|ico|zip|tgz|gz|rar|bz2|doc|xls|exe|ppt|tar|mid|midi|wav|bmp|rtf)$ {
                access_log off; log_not_found off; expires max;
        }

        location = /robots.txt { access_log off; log_not_found off; }
        location ~ /. { deny  all; access_log off; log_not_found off; }
}

/etc/php/7.4/fpm/pool.d/www.conf
Some highlights from that file (it is pretty long…)

user = www-data
group = www-data
listen = 127.0.0.1:9000
listen.owner = www-data
listen.group = www-data
listen.mode = 0660

Could you please help me in troubleshooting?

One Answer

Finally I made it work with the following set up... Here goes configuration which works for me.

Preconditions. Importnant!

  • VPS congiguration: Ubuntu 18.04, Nginx + Php7.4-fpm + MariaDB + PHPMyAdmin. If you have the same package, fell free to copy-paste conf listings, he he
  • Tested on Google Cloud instance, Amazon EC2 and Scaleway. In case of scaleway - some tweaks are required (like by default non root users can not run sudo command on Ubuntu 18.04 instance e.t.c.)
  • If you are using different from 7.4 PHP-fpm ver make sure to reflect that in configuration
  • This works for single site configuration with Letsencrypt SSL (there are many nice written instructures of how to set up Letsencrypt SSL with CertBot)
  • BTW if you are using Cloudflare you might get redirect loop ERRTOOMANY_REDIRECTS Make sure to configurate SSL on Cloudflare side as well.

Corrections are welcomed

/etc/nginx/nginx.conf

user www-data;
# Check how many CPU cores do you have. There are 2 virtual cores are available on my VPS 
worker_processes 2;
pid /run/nginx.pid;
include /etc/nginx/modules-enabled/*.conf;

events {
        worker_connections 768;
        multi_accept on;
}

http {

        #FastCGI cache settings
        fastcgi_cache_path /etc/nginx/cache levels=1:2 keys_zone=WORDPRESS:100m max_size=4g inactive=60m use_temp_path=off;
        fastcgi_cache_key "$scheme$request_method$host$request_uri";
        #
        fastcgi_buffers 8 16k;
        fastcgi_buffer_size 32k;
        fastcgi_connect_timeout 300;
        fastcgi_send_timeout 300;
        fastcgi_read_timeout 300;
        
        fastcgi_cache_background_update on;
        ##
        # Basic Settings
        ##

        sendfile on;
        tcp_nopush on;
        tcp_nodelay on;
        keepalive_timeout 15;
        types_hash_max_size 2048;
        server_tokens off;
        client_max_body_size 64m;
        # server_names_hash_bucket_size 64;
        # server_name_in_redirect off;

        include /etc/nginx/mime.types;
        default_type application/octet-stream;

        ##
        # SSL Settings
        ##
        ssl_protocols TLSv1 TLSv1.1 TLSv1.2; # Dropping SSLv3, ref: POODLE
        ssl_prefer_server_ciphers on;

        ##
        # Logging Settings
        ##

        access_log /var/log/nginx/access.log;
        error_log /var/log/nginx/error.log;

        ##
        # Gzip Settings
        ##

        gzip on;

        # gzip_vary on;
        gzip_proxied any;
        gzip_comp_level 2;
        # gzip_buffers 16 8k;
        # gzip_http_version 1.1;
        gzip_types text/plain text/css application/json application/javascript text/xml application/xml application/xml+rss text/javascript;

        # DoS Protection set zone
        # limit_req_zone $binary_remote_addr zone=one:10m rate=3r/s;

        ##
        # Virtual Host Configs
        ##

        include /etc/nginx/conf.d/*.conf;
        include /etc/nginx/sites-enabled/*;

}

/etc/nginx/site-enabled/mysitename.conf

server {
#~~~forward to HTTPS~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 
    listen 80 default_server;
    listen [::]:80 default_server;
    server_name mysitename.com www.mysitename.com;

    return 301 https://$host$request_uri;
    access_log   /var/log/nginx/mysitename_http.access.log;
    error_log    /var/log/nginx/mysitename_http.error.log;
    # error_log off;
    # access_log off;
}

server {
#~~~HTTPS server settings~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
#~~~BASIC settings~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~  
    listen 443 ssl http2 default_server;
    listen [::]:443 ssl http2 default_server;
    server_name mysitename.com mysitename.com;
    root /var/www/html/mysitename.com;
    index index.php;
    access_log   /var/log/nginx/mysitename_https.access.log;
    error_log    /var/log/nginx/mysitename_https.error.log;
    # error_log off;
    # access_log off;
    
#~~~SSL settings~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 
    ssl on; 
    #~~~Certbot managed part~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    ssl_certificate /etc/letsencrypt/live/mysitename.com/fullchain.pem; # managed by Certbot
    ssl_certificate_key //etc/letsencrypt/live/mysitename.com/privkey.pem; # managed by Certbot
    include /etc/letsencrypt/options-ssl-nginx.conf; # managed by Certbot
    ssl_dhparam /etc/letsencrypt/ssl-dhparams.pem; # managed by Certbot
    ssl_session_tickets off;
    #~~~Certbot managed part END~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    
    # HSTS (ngx_http_headers_module is required) (31536000 seconds = 1 year)
    add_header Strict-Transport-Security "max-age=31536000" always;

    # OCSP stapling
    ssl_stapling on;
    ssl_stapling_verify on;

    # verify chain of trust of OCSP response using Root CA and Intermediate certs
    # ssl_trusted_certificate /path/to/root_CA_cert_plus_intermediates;

    # replace with the IP address of your resolver???
    # resolver 127.0.0.1;
    
    add_header Content-Security-Policy-Report-Only "default-src https:; script-src https: 'unsafe-eval' 'unsafe-inline'; style-src https: 'unsafe-inline'; img-src https: data:; font-src https: data:; report-uri /csp-report";
#~~~SSL settings END~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~     

#~~~Caching rules~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 
       # Enable caching
       set $skip_cache 0;
        
        #~~~Skip caching rules~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
        
        # POST requests and urls with a query string should always go to PHP
        if ($request_method = POST) {
                set $skip_cache 1;
        }
        if ($query_string != "") {
                set $skip_cache 1;
        }

        # Don't cache uris containing the following segments
        if ($request_uri ~* "/wp-admin/|/xmlrpc.php|wp-.*.php|/feed/|index.php|sitemap(_index)?.xml") {
                set $skip_cache 1;
        }

        # Don't use the cache for logged in users or recent commenters
        if ($http_cookie ~* "comment_author|wordpress_[a-f0-9]+|wp-postpass|wordpress_no_cache|wordpress_logged_in") {
                  set $skip_cache 1;
        }

        #Don't chache for store/cart/my account/checkout pages
        if ($request_uri ~* "/store.*|/cart.*|/my-account.*|/checkout.*|/addons.*") {
         set $skip_cache 1;
        }

        #Skip cache for WooCommerce query string
        if ( $arg_add-to-cart != "" ) {
          set $skip_cache 1;
        }
 #~~~Caching rules END~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

 #~~~Locations ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 
        # Use cached or actual file if they exists, Otherwise pass request to WordPress
        location / {try_files $uri $uri/ /index.php?$args;}

        location ~ .php$ {
#                          try_files $uri =404;
                          fastcgi_split_path_info ^(.+.php)(/.+)$;
                          fastcgi_pass 127.0.0.1:9000;
                          fastcgi_index index.php;
#                          include fastcgi_params;

                          
####################
set $rt_session "";

        if ($http_cookie ~* "wc_session_cookie_[^=]*=([^%]+)%7C") {
                set $rt_session wc_session_cookie_$1;
        }

        if ($skip_cache = 0 ) {
                more_clear_headers "Set-Cookie*";
                set $rt_session "";
        }

        fastcgi_cache_key "$scheme$request_method$host$request_uri$rt_session";

        try_files $uri =404;


        include fastcgi_params;

        fastcgi_cache_bypass $skip_cache;
        fastcgi_no_cache $skip_cache;

        fastcgi_cache WORDPRESS;
        
        }

        location ~ /purge(/.*) {
            fastcgi_cache_purge WORDPRESS "$scheme$request_method$host$1";
        }

        location ~* ^.+.(ogg|ogv|svg|svgz|eot|otf|woff|mp4|ttf|rss|atom|jpg|jpeg|gif|png|ico|zip|tgz|gz|rar|bz2|doc|xls|exe|ppt|tar|mid|midi|wav|bmp|rtf)$ {
                access_log off; log_not_found off; expires max;
        }

        location = /robots.txt { access_log off; log_not_found off; }
        
        location ~ /. { deny  all; access_log off; log_not_found off; }

        # PHPMyAdmin access protection - please google of how to protect access to PHPMyAdmin. Some preliminary steps are required      
        location /customPHPmyadmin_path {
                        auth_basic "Admin Login";
                        auth_basic_user_file /etc/nginx/pma_pass;
        }

                
}

Answered by 0LEg on December 9, 2021

Add your own answers!

Ask a Question

Get help from others!

© 2024 TransWikia.com. All rights reserved. Sites we Love: PCI Database, UKBizDB, Menu Kuliner, Sharing RPP