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

My situation is this, I have two Docker containers:
Runs PHP-FPM on port 9000
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 :-P
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;
}
}

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

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.

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!

Related

Serve static files using docker, nginx, php-fpm

I'm working with containers in docker
Where I have one from PHP-FPM and another from Nginx.
But I'm having problems with Nginx to serve the static files (css, js)
Return Status Code: 404 Not Found
Nginx configuration
server {
# Set the port to listen on and the server name
listen 80;
listen [::]:80;
# Set the document root of the project
root /var/www/html;
# Set the directory index files
index index.php;
#Set server name
server_name myproject;
# Specify the default character set
charset utf-8;
# Specify the logging configuration
access_log /var/log/nginx/access.log;
error_log /var/log/nginx/error.log;
# Specify what happens when PHP files are requested
location ~* \.php$ {
#try_files $uri =404;
#try_files /index.php = 404;
fastcgi_split_path_info ^(.+\.php)(/.+)$;
fastcgi_pass myproject:9000;
fastcgi_index index.php;
include fastcgi_params;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
fastcgi_param SCRIPT_NAME $fastcgi_script_name;
fastcgi_param PATH_INFO $fastcgi_path_info;
}
location / {
index index.php;
try_files $uri $uri/ /index.php;
include /etc/nginx/mime.types;
}
location ~* \.(jpg|jpeg|png|css|js|ico|xml)$ {
access_log off;
log_not_found off;
expires 360d;
add_header Cache-Control "public";
}
# Specify what happens what .ht files are requested
location ~ /\.ht {
deny all;
}
}
PHP Dockerfile
FROM php:7-fpm
RUN docker-php-ext-install pdo_mysql
COPY . /var/www/html/
EXPOSE 9000
Nginx Dockerfile
FROM nginx:1.12.2
COPY ./default.conf /etc/nginx/conf.d/default.conf
EXPOSE 80
I think the problem, cause service nginx can not find your web project. If you use docker-compose you can use volume, but if not you can add folder project in nginx Dockerfile to /var/www/html
nginx dockerfile
ROM nginx:1.12.2
COPY . /var/www/html/
COPY ./default.conf /etc/nginx/conf.d/default.conf
EXPOSE 80
for docker compose like this :
services:
nginx:
images: nginx:latest
...
...
volumes:
- ./:/var/www/html
php:
images: php
...
...
volumes:
- ./:/var/www/html

nginx sub location with php-fpm config failed

I have an nginx config for my server as follow, I want
when I request service/dev/sync/sync
it will route to /home/work/app-web/src/api/dev/sync.php/sync
match the php rule with $fastcgi_script_name is /dev/sync.php and $fastcgi_path_info is sync
this rule only need for ~ /service/([a-zA-Z]*/[a-zA-Z]*)(/[a-zA-Z]*)$.
But when I request /service/dev/sync/sync, it will return 404 with error
*173 open() "/home/work/nginx/html/dev/sync.php/sync" failed (2: No such file or directory), client: 172.18.17.90, server: localhost, request: "POST /service/dev/sync/sync HTTP/1.1"
/home/work/nginx/html is the default root for my nginx server. the root config is not
work at all.
what's the problem with this config?
server {
set $work_dir /home/work/app-web;
listen 80;
server_name localhost;
location ~ /service/([a-zA-Z]*/[a-zA-Z]*)(/[a-zA-Z]*)$ {
root $work_dir/src/api;
set $file $1;
set $action $2;
try_files $uri $uri/ /$file.php$action$is_args$query_string;
location ~ \.php {
fastcgi_split_path_info ^(.+\.php)/(.*)$;
fastcgi_pass unix:/home/work/app-web/php/var/run/app-web.sock;
fastcgi_index index.php;
fastcgi_param SCRIPT_FILENAME $work_dir/src/api$fastcgi_script_name;
fastcgi_param PATH_INFO $fastcgi_path_info;
fastcgi_param UNIQUE_ID $request_id;
include fastcgi_params;
}
}
}
Root config works fine.
Your problem is that there is an internal redirection to /dev/sync.php/sync?, and the new inner-url does not match the regexp-location
You can activate the debug with
error_log /var/log/nginx/debug.log debug;
The logs look like this :
*1 trying to use file: "/dev/sync.php/sync" "/home/work/app-web/src/api/dev/sync.php/sync"
*1 internal redirect: "/dev/sync.php/sync?"
*1 rewrite phase: 1
*1 http script value: "/home/work/app-web"
*1 http script set $work_dir
*1 test location: ~ "/service/([a-zA-Z]*/[a-zA-Z]*)(/[a-zA-Z]*)$"
*1 using configuration ""
The new URL is /dev/sync.php/sync?, and this url matches with no location, because the regexp /service/([a-zA-Z]/[a-zA-Z])(/[a-zA-Z]*)$ is not intended for the inner-URL.
I suggest you another configuration :
server {
set $work_dir /home/work/app-web;
listen 80;
server_name localhost;
location ~ /service/([a-zA-Z]*/[a-zA-Z]*)(/[a-zA-Z]*)$ {
root $work_dir/src/api/;
set $file $1;
set $action $2;
rewrite .* /src/api/$file.php$action last;
}
location ~ \.php {
internal;
root $work_dir;
fastcgi_split_path_info ^(.+\.php)/(.*)$;
fastcgi_pass unix:/home/work/app-web/php/var/run/app-web.sock;
fastcgi_index index.php;
fastcgi_param SCRIPT_FILENAME $document_root/$fastcgi_script_name;
fastcgi_param PATH_INFO $fastcgi_path_info;
fastcgi_param UNIQUE_ID $request_id;
include fastcgi_params;
}
error_log /var/log/nginx/test-error.log debug;
}
Note the internal; directive

OROCRM Nginx Virtual Host Configuration Not Working

I have installed a orocrm on a AWS Lightsail VPS with Nginx & PHP7. orocrm installed without a hitch but I'm using Nginx for the first time and my virtual host doesn't seem to be working.
sites-available/default:
server {
listen 80 default_server;
listen [::]:80 default_server;
root /var/www/html;
index app.php index.php index.html;
server_name 34.127.224.10;
location / {
try_files $uri $uri/ =404;
}
location ~ \.php$ {
fastcgi_pass unix:/run/php/php7.0-fpm.sock;
fastcgi_index index.php;
fastcgi_param SCRIPT_FILENAME /scripts$fastcgi_script_name;
include fastcgi_params;
}
location ~ /\.ht {
deny all;
}
}
I then purchased & pointed crmdomain.com to my instance and created another file.
sites-available/crm:
server {
listen 80;
server_name crmdomain.com www.crmdomain.com;
root /var/www/html/crm/web;
index app.php;
error_log /var/log/nginx/orocrm_error.log;
access_log /var/log/nginx/orocrm_access.log;
location = /favicon.ico { access_log off; log_not_found off; }
location = /robots.txt { access_log off; log_not_found off; }
location #rewrite { rewrite ^/(.*)$ /app.php/$1; }
location / {
try_files $uri /app.php$is_args$args;
}
location ~ [^/]\.php(/|$) {
fastcgi_split_path_info ^(.+?\.php)(/.*)$;
if (!-f $document_root$fastcgi_script_name) {
return 404;
}
fastcgi_index app.php;
fastcgi_read_timeout 10m;
fastcgi_pass unix:/run/php/php7.0-fpm.sock;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
include fastcgi_params;
}
}
I honestly don't know most of what is above, it's mostly based on tutorial and apache experience.
Errors
Domain based
- crmdomain.com -> 403 Forbidden nginx/1.10.0 (Ubuntu)
- crmdomain.com/app.php -> No input file specified.
- crmdomain.com/app_dev.php -> No input file specified.
- crmdomain.com/index.nginx-debian.html -> Welcome to nginx!
- crmdomain.com/user/login -> 404 Not Found nginx/1.10.0 (Ubuntu) **This is what should word**
Static IP based
- 34.127.224.10 -> 403 Forbidden nginx/1.10.0 (Ubuntu)
- 34.127.224.10/crm/web/ - No input file specified.
- 34.127.224.10/crm/web/app.php - No input file specified.
- 34.127.224.10/crm/web/app_dev.php - No input file specified.
- 34.127.224.10/index.nginx-debian.html -> Welcome to nginx!
- 34.127.224.10/crm/web/app.php/user/login -> 404 Not Found nginx/1.10.0 (Ubuntu) **This is what should word**
What am I doing wrong?
It's weird how often I answer my own questions:
I was able to change the default files and remove the extra virtual host. Since the server was only going to host the one app.
server {
listen 80 default_server;
listen [::]:80 default_server;
server_name 34.127.224.10 crmdomain.com www.crmdomain.com;
root /var/www/html/crm/web;
index app.php app_dev.php index.php;
location / {
# try to serve file directly, fallback to app.php
try_files $uri /app.php$is_args$args;
}
location ~ ^/(app|app_dev|config|install)\.php(/|$) {
#fastcgi_pass 127.0.0.1:9000;
# or
fastcgi_pass unix:/run/php/php7.0-fpm.sock;
fastcgi_split_path_info ^(.+\.php)(/.*)$;
include fastcgi_params;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
fastcgi_param HTTPS off;
}
error_log /var/log/nginx/orocrm_error.log;
access_log /var/log/nginx/orocrm_access.log;
}

Symfony + nginx virtual host configuration not working

Created a virtualhost for symfony application in local system
Here is the nginx config file
server {
listen 80;
server_name local.symfony;
root /home/guest/symfony_demo/web;
rewrite ^/app\.php/?(.*)$ /$1 permanent;
try_files $uri #rewriteapp;
location #rewriteapp {
rewrite ^(.*)$ /app.php/$1 last;
}
# Deny all . files
location ~ /\. {
deny all;
}
location ~ ^/(app|app_dev)\.php(/|$) {
fastcgi_split_path_info ^(.+\.php)(/.*)$;
include fastcgi_params;
fastcgi_param SCRIPT_FILENAME
$document_root$fastcgi_script_name;
fastcgi_index app.php;
send_timeout 1800;
fastcgi_read_timeout 1800;
fastcgi_pass unix:/var/run/php5-fpm.sock;
}
# Statics
location /(bundles|media) {
access_log off;
expires 30d;
try_files $uri #rewriteapp;
}
error_log /var/log/nginx/project_error.log;
access_log /var/log/nginx/project_access.log;
}
On load of app in browser its throwing an error
502 Bad Gateway Error:No input file specified.
Error caught from error.log file:
FastCGI sent in stderr: "Unable to open primary script: /home/guest/symfony_demo/web/app.php (No such file or directory)" while reading response header from upstream, client: 127.0.0.1, server: local.symfony, request: "GET / HTTP/1.1", upstream: "fastcgi://unix:/var/run/php5-fpm.sock:", host: "local.symfony"
Can anyone help me to configure symfony app to app_dev config file.
Any thoughts??
fastcgi_param SCRIPT_FILENAME $realpath_root$fastcgi_script_name;
This line is the problem. If you remove it, your error disappears. You may then have Opcache problems due to Symfony using symlinks to the current project.
With $realpath_root$fastcgi_script_name, the web server looks at the "real" path for the PHP script based on the root definition in your server block. Nginx must have read permissions to the path for this to work. Your code is in /home/guest/, if nginx is running as "www-data" give it permissions to your directories, or run nginx as the "guest" user (ignoring the security implications of this).
Why don't you start with configuration from official documentation (http://symfony.com/doc/current/cookbook/configuration/web_server_configuration.html#nginx) and when that works, you can try to add your custom configuration (caching of sttaic files ...) ?
This should work:
server {
listen 80;
server_name local.symfony;
root /home/guest/symfony_demo/web;
location / {
try_files $uri /app_dev.php$is_args$args;
}
location ~ ^/(app_dev|config)\.php(/|$) {
fastcgi_pass unix:/var/run/php5-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;
}
error_log /var/log/nginx/project_error.log;
access_log /var/log/nginx/project_access.log;
}
This error happens when nginx is not able to find the php-fpm.sock file.
Can you make sure that the php-fpm.sock file is in the path as mentioned. I had to update fastcgi_pass like below
fastcgi_pass unix:/var/run/php-fpm/php-fpm.sock;
as my php-fpm.sock was there

Does nginx fastcgi_pass support variables?

I would like to use dynamic host resolution with nginx and fastcgi_pass.
When fastcgi_pass $wphost:9000; is set in the conf then nginx displays the error
[error] 7#7: *1 wordpress.docker could not be resolved (3: Host not found),
but when I set fastcgi_pass wordpress.docker:9000;it is working except for the fact the that after a wordpress restart nginx still points to an old ip.
server {
listen [::]:80;
include /etc/nginx/ssl/ssl.conf;
server_name app.domain.*;
root /var/www/html;
index index.php index.html index.htm;
resolver 172.17.42.1 valid=60s;
resolver_timeout 3s;
location / {
try_files $uri $uri/ /index.php?q=$uri&$args; ## First attempt to serve request as file, then as directory, then fall back to index.html
}
#error_page 404 /404.html;
error_page 500 502 503 504 /50x.html;
location = /50x.html {
root /usr/share/nginx/html;
}
set $wphost wordpress.docker;
# pass the PHP scripts to FastCGI server listening on wordpress.docker
location ~ \.php$ {
client_max_body_size 25M;
try_files $uri =404;
fastcgi_split_path_info ^(.+\.php)(/.+)$;
fastcgi_pass $wphost:9000;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
fastcgi_param SCRIPT_NAME $fastcgi_script_name;
fastcgi_index index.php;
include fastcgi_params;
}
location ~* \.(jpg|jpeg|gif|png|css|js|ico|xml)$ {
add_header Pragma public;
add_header Cache-Control "public, must-revalidate, proxy-revalidate";
access_log off;
log_not_found off;
expires 168h;
}
# deny access to . files, for security
location ~ /\. {
access_log off;
log_not_found off;
deny all;
}
}
I have different virtual host configuration where I use proxy_pass http://$hostname; and in this setup everything is working as expected and the host is found.
After trying different options I wonder if fastcgi_pass does support variables
It does work if you pass the upstream as a variable instead, for example:
upstream fastcgi_backend1 {
server php_node1:9000;
}
upstream fastcgi_backend2 {
server php_node2:9000;
}
server {
listen 80;
server_name _;
set $FASTCGI_BACKEND1 fastcgi_backend1;
set $FASTCGI_BACKEND2 fastcgi_backend2;
location ~ ^/site1/index.php$ {
fastcgi_pass $FASTCGI_BACKEND1;
}
location ~ ^/site2/index.php$ {
fastcgi_pass $FASTCGI_BACKEND2;
}
}

Categories