FPM/Nginx: unable to open primary script - nginx

I'm struggling to get NGINX and PHP-FPM to talk effectively. My NGINX configuration file includes the following definition for the api offset:
location /api {
try_files $uri /api/index.php$is_args$args;
gzip off;
fastcgi_pass PHP:9000;
fastcgi_index index.php;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
fastcgi_keep_conn off;
include fastcgi_params;
}
and on my PHP machine I have the following Pool configuration:
[api]
listen = 9000
user = www-data
group = www-data
pm = dynamic
pm.max_children = 10
pm.start_servers = 3
pm.min_spare_servers = 2
pm.max_spare_servers = 5
pm.status_path = /status
I then tail the NGINX server's log file and when hitting the webserver with:
http://localhost/api
# or
http://localhost/api/index.php
# or ...
http://localhost/api/resources.json
I can see from the NGINX server log that NGINX is correctly matching the /api pattern but i get the following errors:
[error] 14#0: *1 FastCGI sent in stderr: "Unable to open primary script: /app/html/websites/couchbase/api/index.php (No such file or directory)"
Where the root directory on the PHP machine is /app/html/websites/couchbase. I'm at a complete loss on what this error really means or more importantly how to debug it from here. Any help would be greatly appreciated.
p.s. I have tried replacing $document_root reference in the fast_cgi_param to hard coded values to see if it makes a difference. It does in the sense that if I point it at an incorrect directory it gives me
a No input file specified. error. The only place where I get the error is when it seemingly is pointed to the right place.
Added this in case it helps clarify ... this is the file system at /app/html/websites/couchbase/api on the PHP/FPM machine.
I created the test.php file which basically just echo's "Ok" back but that works no better than the primary goal of running index.php.
note: I wasn't sure if execution permissions were important -- as you can see test.php does not have them set in the picture -- but I've tried them both ways and it appears to make no difference.

The error is complaining about the index.php file not found in the root directory. Is it under ...couchbase/api or is in under .../couchbase? In the second case you can fix this problem with a redirection.
I think you can move try_files outside the location block. I never used $is_args and $args in this kind of redirection, and I've not tested it but IMHO I think you can remove it.
I think you can fix this problem with this configuration:
root /app/html/websites/couchbase;
try_files $uri /api/index.php$is_args$args;
location /api {
rewrite /api/(.*) $1 break;
gzip off;
fastcgi_pass PHP:9000;
fastcgi_index index.php;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
fastcgi_keep_conn off;
include fastcgi_params;
}
You can have a cleaner config file if you'll include the following directives:
fastcgi_index index.php;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
fastcgi_keep_conn off;
inside the fastcgi_params file.

Related

Why is my site downloaded instead of running?

I'm trying to install Wordpress on a Ubuntu 18.04 on a subdomain. I set the Nginx files on sites-available, but I get a 502 error on browser because Wordpress is using a .php file type for the index, so I added "index.php" on the list in sites-available. Well after adding "index.php" on the list when I try to access the URL in browser it downloads a file named with the subdomain address.
Here's my code in sites-available
server {
listen 80;
listen [::]:80;
root /var/www/apt;
# Add index.php to the list if you are using PHP
index index.html index.htm index.nginx-debian.html index.php;
server_name apt.forrum.ro;
location / {
# First attempt to serve request as file, then
# as directory, then fall back to displaying a 404.
try_files $uri $uri/ =404;
}
}
Please let me know how to fix it.
This is simplified, basically Nginx uses the try_files directive to serve the file to user in the folder. This is why your php file is being sent to the user, it's then downloaded rather than shown as browsers don't really know how to show PHP to the user.
What you need to do is tell Nginx to run the file. In the case of PHP you can use FastCGI. There are many guides to doing this on ubuntu such as This One.
Once you have it installed, all the directives for FastCGI are described by Nginx themselves Here.
Their example is posted here:
location ~ [^/]\.php(/|$) {
fastcgi_split_path_info ^(.+?\.php)(/.*)$;
if (!-f $document_root$fastcgi_script_name) {
return 404;
}
# Mitigate https://httpoxy.org/ vulnerabilities
fastcgi_param HTTP_PROXY "";
fastcgi_pass 127.0.0.1:9000;
fastcgi_index index.php;
# include the fastcgi_param setting
include fastcgi_params;
# SCRIPT_FILENAME parameter is used for PHP FPM determining
# the script name. If it is not set in fastcgi_params file,
# i.e. /etc/nginx/fastcgi_params or in the parent contexts,
# please comment off following line:
# fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
}

VPS 2GB RAM memory and Symfony 3 - Out of memory

I'm trying to install a symfony 3.4 project on a Debian 8 server. I'm using Nginx as web server.
My config server :
RAM = 2 GB
Memory 20 GB
The composer install works fine (the composer update too).
I had also an angular front in the same server. Everything had works fine (npm install, ng build, ..).
But when I request any route of my API, I get an error with code 500. I can't even get the profiler.
Inside the log file of nginx, I can see this error message log message but I configured the php memory_limit = -1.
My nginx conf file :
server {
listen 80;
server_name my_server_name;
root location/of/my/front;
index index.html index.htm;
location / {
try_files $uri $uri/ /index.html;
}
}
server {
server_name my_server_name_api;
root location/of/my/api/web;
location / {
try_files $uri /app.php$is_args$args;
}
location ~ ^/(app_dev|config)\.php(/|$) {
fastcgi_pass unix:/var/run/php/php7.2-fpm.sock;
fastcgi_split_path_info ^(.+\.php)(/.*)$;
include fastcgi_params;
fastcgi_param SCRIPT_FILENAME $realpath_root$fastcgi_script_name;
fastcgi_param DOCUMENT_ROOT $realpath_root;
}
location ~ ^/app\.php(/|$) {
fastcgi_pass unix:/var/run/php/php7.2-fpm.sock;
fastcgi_split_path_info ^(.+\.php)(/.*)$;
include fastcgi_params;
fastcgi_param SCRIPT_FILENAME $realpath_root$fastcgi_script_name;
fastcgi_param DOCUMENT_ROOT $realpath_root;
internal;
}
location ~ \.php$ {
return 404;
}
error_log /var/log/nginx/project_error.log;
access_log /var/log/nginx/project_access.log;
}
Do you have any idea ?
Thanks
This error could be due to your PHP.ini settings file having a low limit of memory, PHP can have a set limit of memory that it's allowed to use, and typically it's not set dynamically meaning that it requires you to change it to the value that you want to use.
To do this, find the php.ini file, and find the line with memory_limit on it and then change it to:
memory_limit = -1
This will allow PHP to use as much ram as it can, this is not ideal in some situations, and often times you'll find most websites only need around 1gb of memory to run, so try:
memory_limit = 1024
Instead, you could look at other methods such as disabling profiler in Symfony if you are not intending on using it as it's the most eager component within Symfony. To do this add this snippet to your code and it will where you would like to disable profiler:
if ($this->container->has('profiler')){
$this->container->get('profiler')->disable();
}
or if you want to disable to globally you can set the global parameter within the config.
framework:
profiler:
collect: false
You can also set the memory_limit vairable via PHP by putting ini_set('memory_limit', '-1'); into your main .php file.

1 nginx server multiple php servers

what i am missing?
lets say this simple conf:
upstream php {
server 111.1111.1111.1111:9000;
}
server {
listen 80 reuseport;
root /var/www/html/public/;
index index.php;
location / {
set $orig_uri $uri;
try_files $uri $uri/ /index.php?$query_string;
}
location ~ \.php$ {
ssi on;
include snippets/fastcgi-php.conf;
fastcgi_param REQUEST_URI $orig_uri$is_args$args;
fastcgi_cache_key "$scheme$request_method$orig_uri$is_args$args";
add_header X-Cache-Key $scheme$request_method$orig_uri$is_args$args;
add_header X-Cache $upstream_cache_status;
# With php5-cgi alone:
#fastcgi_pass 127.0.0.1:9000;
# With php5-fpm:
#fastcgi_pass unix:/var/run/php5-fpm.sock;
fastcgi_pass php;
}
}
how does nginx gonna access "/var/www/html/public/" on different server? how will it know if the file exists or not exists? I tried to play with it and I always get
404 Not Found
So i am missing something but cant understand what, if the php servers dont have nginx installed
How does nginx gonna access "/var/www/html/public/" on different
server? how will it know if the file exists or not exists?
nginx cannot determine if the file exists on the upstream PHP service. It will pass a script pathname to the PHP service and if it does not exist, the PHP service will return a 404 response.
The PHP service probably uses the fastcgi_param SCRIPT_FILENAME parameter to find the upstream script file. The parameter should be defined in your snippets/fastcgi-php.conf file.
This is usually set to a value of $document_root$fastcgi_script_name. The value for $document_root being set by the root directive in your configuration file.
This will only work if the scripts on the upstream server are placed in the exact same directory hierarchy as specified by the nginx server. Otherwise, you may need to handcraft the value of the SCRIPT_FILENAME parameter.

How to set DOCUMENT_ROOT and SCRIPT_NAME correctly for fcgiwrap

I've got a simple script cpuinfo.sh that works and is executable.
I'm getting an error
*224 FastCGI sent in stderr: "Cannot get script name, are DOCUMENT_ROOT and SCRIPT_NAME (or SCRIPT_FILENAME) set and is the script executable?" while reading response header from upstream, client: 86.44.146.39, server: staging.example.com, request: "GET /cpuinfo.sh HTTP/1.1", upstream: "fastcgi://unix:/var/run/fcgiwrap.socket:", host: "staging.example.com"
the nginx settings are
location ~ (\.cgi|\.py|\.sh|\.pl|\.lua)$ {
gzip off;
autoindex on;
fastcgi_pass unix:/var/run/fcgiwrap.socket;
include fastcgi_params;
fastcgi_param DOCUMENT_ROOT /home/balance/balance-infosystems-web/scripts/;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
}
I'm expecting fcgiwrap to execute
/home/balance/balance-infosystems-web/scripts/cpuinfo.sh
I hard coded the script path to debug but I'm still getting the same error.
location ~ (\.cgi|\.py|\.sh|\.pl|\.lua)$ {
gzip off;
autoindex on;
fastcgi_pass unix:/var/run/fcgiwrap.socket;
include fastcgi_params;
fastcgi_param DOCUMENT_ROOT /home/balance/balance-infosystems-web/scripts/;
# fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
fastcgi_param SCRIPT_FILENAME /home/balance/balance-infosystems-web/scripts/cpuinfo.sh;
}
What needs to be changed in the nginx server config to execute the script correctly?
I had the same problem. After too many hours of searching in the wrong direction, I finally found the cause. In hindsight the solution was here all the time, right above, but I realise that only now.
For some reason in my case DOCUMENT_ROOT had the value /var/www/cgi-bin, and SCRIPT_NAME was /cgi-bin/somescript.cgi . So if you put those together in the usual way, by writing
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name ,
SCRIPT_FILENAME gets set to /var/www/cgi-bin/cgi-bin/somescript.cgi, which is a bit overdone and therefore doesn't work. The fix was to put:
fastcgi_param SCRIPT_FILENAME /var/www$fastcgi_script_name
Now if only FastCGI, in the error.log via fcgiwrap, had not WONDERED if the variables were set, but instead had TOLD me what they WERE set to, I'd have seen the solution immediately. The golden rule of diagnostic information: be specific and precise.
I only found out after running a printenv script I had lying about somewhere, first stating its SCRIPT_FILENAME explicitly, to be able to run it in the first place.
I discovered that DOCUMENT_ROOT can not be reset.
I normally have scripts directories away from publicly accessible paths.
I knew that the scripts directory was the same level the web directory so I tried.
location ~ (\.cgi|\.py|\.sh|\.pl|\.lua)$ {
gzip off;
autoindex on;
fastcgi_pass unix:/var/run/fcgiwrap.socket;
fastcgi_param SCRIPT_FILENAME $document_root/../scripts/$fastcgi_script_name;
include fastcgi_params ;
}
which resolved the issue.
As others have mentioned this can be a pain to debug, but strace is super helpful:
strace -f -e trace=lstat64 -p $(pidof fcgiwrap)
Tells strace to follow forks -f, only trace syscalls to lstat64, and tells it to attach to the PID -p of fcgiwrap. You should get an output along the lines of:
[pid 1918] lstat64("{The file fastcgi is trying to load}", 0xbee94a50) = -1 ENOENT (No such file or directory)

Nginx, fastcgi PHP Windows, No input file specified

Running php-cgi on port 9000
Netstat gives me
TCP 127.0.0.1:9000 DESKTOP-xxxxxxx:0 LISTENING
[php-cgi.exe]
nginx.conf
http://pastebin.com/wkfz8wxw
Every php file gives me this No input file specified. error...
Changed SCRIPT_FILENAME to SCRIPT_NAME and no succes..
I am on Windows 10 Home x64
You need to set a document root with the root directive, either within your location ~ \.php$ block or inherited from the outer server block.
The solution may be to move the root c:/Users/Youri/PhpstormProjects; line out of your location / block into a position above it.
Usually fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name; is the correct method to specify the full path to the script, whereas SCRIPT_NAME is usually just the last element.
Like this:
server {
...
root c:/Users/Youri/PhpstormProjects;
location / {
index index.html index.htm index.php;
}
location ~ \.php$ {
fastcgi_pass 127.0.0.1:9000;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
include fastcgi_params;
}
}
Set root directive with absolute path in windows PC.
Check for the case or any typing mistake in the path.
Reload the nginx process.
May be the root path problem. I used the backslash \ on Windows and found this issue.
server {
location ~ \.php$ {
- root C:\Users\name\ProjectOfPHP; # 404
+ root C:/Users/name/ProjectOfPHP; # Use this pattern
}
}

Resources