php-fpm: File not found in kubernetes - php

I'm trying to set a k8s deployment with 2 pods (nginx + php-fpm), but I can't get php-fpm to execute the php scripts. The webpage displays File not found., and in logs :
fpm pod : 192.168.3.187 - 13/Nov/2020:16:44:06 +0000 "GET /index.php" 404
nginx pod : 2020/11/13 16:44:06 [error] 20#20: *1 FastCGI sent in stderr: "Primary script unknown" while reading response header from upstream, client: 192.168.1.45, server: _, request: "GET / HTTP/1.1", upstream: "fastcgi://10.98.178.35:9000", host: "192.168.1.220"
The .html files are served as expected.
Without the Location ~ \.php$ server block of nginx I'm able to download .php files, so the problem is really with php-fpm; when entering the container, I can see the scripts are present.
In my deployment, a PersistentVolume on an NFS is mounted on both pods, in /app. Nginx is configured with this configMap :
default.conf: |
server {
listen 80 default_server;
server_name _;
add_header X-Backend-Server $hostname;
root /app;
index index.php index.html;
location / {
try_files $uri $uri/ =404;
}
location ~ \.php$ {
include fastcgi_params;
fastcgi_param REQUEST_METHOD $request_method;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
fastcgi_pass phpfpm-deploy-svc.default.svc.cluster.local:9000;
}
}
Where phpfpm-deploy-svc.default.svc.cluster.local is the DNS resolution of the PHP-FPM service (irrelevant to paste the service code).
php-fpm is a classic deployment :
spec:
containers:
- name: phpfpm
image: php:7.3-fpm
ports:
- containerPort: 9000
volumeMounts:
- name: nfs-volume
mountPath: /app
volumes:
- name: nfs-volume
persistentVolumeClaim:
claimName: nfs-pvc
with its own service :
apiVersion: v1
kind: Service
metadata:
name: phpfpm-deploy-svc
spec:
ports:
- port: 9000
selector:
app: phpfpm-deploy
type: ClusterIP
Most of the solutions seen here are related to the line fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;: that's possible, but I still has to find a working one.
Without k8s (only docker-compose), I can create this configuration witout issue.

Well, my code above is working fine : the NFS server was the problem, it wasn' doing any mapping on users.
So I was able, from containers, to list the files on the NFS volume as root... but not as www-data, which is the user running php-fpm.
Setting correct mapping on the NFS volume solved it.

Related

Nginx - wordpress fpm - getting 404 on images stored in wp-content/uploads (symbolic link to EFS)

I am running Nginx and wordpress-fpm in Kubernetes within one pod. Images are stored in EFS and EFS folder linked to wp-content/uploads folder as a symbolic link. EFS folder is available and I can access it from the container.
This is my deployment file:
apiVersion: apps/v1
kind: Deployment
metadata:
name: -deployment
labels:
app: MASSEDIT
spec:
replicas: 1
selector:
matchLabels:
app: MASSEDIT
template:
metadata:
labels:
app: MASSEDIT
spec:
volumes:
- name: efs-pvc
persistentVolumeClaim:
claimName: -efs-storage-claim
- name: shared-files
emptyDir: {}
- name: nginx-config
configMap:
name: -nginx-configmap
containers:
- image: DONTTOUCH-replace-me-kustomization
name: app
ports:
- containerPort: 9000
protocol: TCP
volumeMounts:
- mountPath: /var/www/html
name: shared-files
- mountPath: /shared
name: efs-pvc
- image: nginx
name: nginx
ports:
- containerPort: 80
protocol: TCP
volumeMounts:
- mountPath: /var/www/html
name: shared-files
- mountPath: /etc/nginx/conf.d/default.conf
name: nginx-config
subPath: nginx.conf
This is my Nginx config map:
kind: ConfigMap
apiVersion: v1
metadata:
name: -nginx-configmap
data:
nginx.conf: |
server {
listen 80;
server_name some server;
root /var/www/html/;
index index.php index.html index.htm;
# Logs
access_log /var/log/nginx/webapp-access.log;
error_log /var/log/nginx/webapp-error.log;
location / {
# try_files $uri $uri/ =404;
# try_files $uri $uri/ /index.php?q=$uri&$args;
try_files $uri $uri/ /index.php?$query_string;
}
location ~ \.php$ {
fastcgi_param HTTPS 1;
fastcgi_split_path_info ^(.+\.php)(/.+)$;
fastcgi_pass 127.0.0.1:9000;
fastcgi_index index.php;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
include fastcgi_params;
fastcgi_buffers 8 16k;
fastcgi_buffer_size 32k;
fastcgi_connect_timeout 300s;
fastcgi_send_timeout 60;
fastcgi_read_timeout 60;
}
}
I am able to load all pages and everything works fine except media (images) that are stored in wp-content/uploads. I am getting 404 on loading this images.
My nginx by default running as root.
wp-content folder owner is www-data:www-data
There is nothing in the fpm log or nginx error log.
Cant understand and debug the root cause. Is it possible that Nginx is not folowing symbolic links?
UPD1.
I was checking nginx and nginx container and I am not able to access the symbolic link from it. So my symbolic link is created in app container and nginx is not able to see it.
So the solution:
efs need to be mounted to both containers at the same path, so both containers are able to access it.

FastCGI sent in stderr: "Primary script unknown" while reading response header from upstream nginx error

I user nginx docker as proxy server, and there are other containers running: nuxt.js and php-fpm.
This is my fpm's conf file:
server {
server_name fpm.me.com;
root /var/www/fpm/html;
location / {
# try to serve file directly, fallback to index.php
try_files $uri /index.php$is_args$args;
}
#location ~ ^/index\.php(/|$) {
# https://stackoverflow.com/questions/68350978/nginx-serving-only-but-not-any-other-files
location ~ \.php(/|$) {
fastcgi_pass fpm:9000;
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;
}
access_log off;
error_log /dev/stderr;
}
But when I type fpm.me.com, I get this error in nginx's log file:
2021/08/03 09:31:18 [error] 31#31: *13 FastCGI sent in stderr: "Primary script unknown" while reading response header from upstream, client: MY_IP, server: fpm.me.com, request: "GET / HTTP/1.1", upstream: "fastcgi://172.20.0.8:9000", host: "fpm.me.com"
I saw other answers in StackOverFlow, ServerFault and other websites but it seems it did not help me.
This doesn't look valid:
fastcgi_pass fpm:9000
You have 2 options:
use a unix socket:
fastcgi_pass unix:/run/php/php7.4-fpm.sock;
use TCP port
fastcgi_pass 127.0.0.1:9000;
Option 1 is slightly faster and doesn't have the risk of ports exhaustion if you receive many concurrent connections.
The issue was with the volumes I mounted for nginx and fpm which were not the same.
This is my compose file:
services:
nginx:
image: nginx
volumes:
- './fpm/:/var/www/fpm/'
fpm:
image: custom
volumes:
- './fpm/:/var/www/'
While it should have been like this to work:
services:
nginx:
image: nginx
volumes:
- './fpm/:/var/www/fpm/'
fpm:
image: custom
volumes:
- './fpm/:/var/www/fpm/'

How to configure an nginx.conf with a dockerised drupal website?

this is my first time working with nginx and I'm using it to access my dockerised drupal appliction from a production subdomain.
So before everything, I'm currently using docker-compose to create my sql, app, and webservice containers, here is my docker-compose file :
version: '3'
services:
app:
image: osiolabs/drupaldevwithdocker-php:7.4
volumes:
- ./docroot:/var/www/html:cached
depends_on:
- db
restart: always
container_name: intranet
db:
image: mysql:5.5
volumes:
- ./mysql:/var/lib/mysql
restart: always
environment:
- MYSQL_ROOT_PASSWORD=linux1354web
- MYSQL_USER=root
- MYSQL_PASSWORD=linux1354web
- MYSQL_DATABASE=intranet
container_name: intranet-db
web:
build: ./web
ports:
- 88:80
depends_on:
- app
volumes:
- ./docroot:/var/www/html:cached
restart: always
container_name: webIntranet
I don't think the containers are the problem, as when I go to the drupal containers the site works, but my main problem is the link with the nginx container. Here is my nginx.conf :
# stuff for http block
client_max_body_size 1g;
# fix error: upstream sent too big header while reading response header from upstream
fastcgi_buffers 16 16k;
fastcgi_buffer_size 32k;
server {
listen 80;
listen [::]:80 default_server;
server_name _;
index index.php index.html;
error_log /var/log/nginx/error.log;
access_log /var/log/nginx/access.log;
root /var/www/html;
#RENVOYER LA PAGE DE GARDE DE APACHE2
location / {
# try to serve file directly, fallback to app.php
try_files $uri /index.php?$query_string; # For Drupal >= 7
}
location /intranet {
# try to serve file directly, fallback to app.php
try_files $uri $uri/;
}
#RENVOYER LE FICHIER ROBOTS.TXT
location = /robots.txt {
allow all;
log_not_found off;
access_log off;
}
location = /favicon.ico {
log_not_found off;
access_log off;
}
location ~ \.php(/|$) {
try_files $uri =404;
fastcgi_split_path_info ^(.+\.php)(/.+)$;
fastcgi_pass app:80;
fastcgi_index index.php;
include fastcgi_params;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
fastcgi_param DOCUMENT_ROOT $document_root;
}
}
And this is my DockerFile to build nginx image:
FROM nginx:alpine
COPY nginx.conf /etc/nginx/conf.d/default.conf
When I go to localhost:88/ I currently have a apache2 hub page, but the moment I'm trying for another page I always get a 502 bad gateway error and the logs are saying :
webIntranet | 2021/03/11 08:44:55 [error] 30#30: *1 upstream sent unsupported FastCGI protocol version: 72 while reading response header from upstream, client: 172.26.0.1, server: _, request: "GET /index HTTP/1.1", upstream: "fastcgi://172.26.0.3:80", host: "localhost:88"
To go more into details, my docker folder looks like that, docroot containes the drupal website.
I have tried sovling the problem by changing the ports as some solution mentionned it but it did nothing, I don't understand what could be wrong, I've tried many things with the conf but none of them works, and I still even can't have a single page of the drupal site showing up.
The drupaldevwithdocker-php project isn't using php-fpm, hence the response is unsupported as it's from apache rather than php-fpm. I'd imagine you'd need something more like this?
proxy_pass http://app:80;
See https://gist.github.com/BretFisher/468bca2900b90a4dddb7fe9a52143fc6

Convert docker-compose to Kubernetes for nginx & php-fpm containers

I have a dockerized symfony project and I'm trying to delpoy it in GPC on Kubernetes cluster.
In development I use docker-compose and I have two sepparate containers for php-fpm and nginx.
When I run docker-compose up --build, it all works fine, but when I try to create a kubernetes cluster I get this error after I run kubectl apply -f nginx.deployment.yaml:
nginx: [emerg] host not found in upstream "php-fpm" in /etc/nginx/conf.d/default.conf:11
This is the nginx default.conf file:
server {
listen 80;
server_name localhost;
root /app/public;
location / {
try_files $uri /index.php$is_args$args;
}
location ~ ^/index\.php(/|$) {
fastcgi_pass php-fpm:9000;
fastcgi_split_path_info ^(.+\.php)(/.*)$;
include fastcgi_params;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
fastcgi_param DOCUMENT_ROOT $document_root;
internal;
}
location ~ \.php$ {
return 404;
}
}
Please note
fastcgi_pass php-fpm:9000;
which references the php-fpm container.
Dockerfile for nginx:
ARG VERSION
# Dev image
FROM nginx:${VERSION}-alpine as dev
# Copy nginx config
COPY ./docker/nginx/default.conf /etc/nginx/conf.d/default.conf
# Prod image
FROM dev as prod
# Copy assets
COPY ./assets /app/public
Here it is the nginx.deployment.yaml file:
apiVersion: apps/v1
kind: Deployment
metadata:
annotations:
kompose.cmd: kompose convert -f ../docker-compose.yml
kompose.version: 1.22.0 (955b78124)
creationTimestamp: null
labels:
io.kompose.service: nginx
name: nginx
spec:
replicas: 1
selector:
matchLabels:
io.kompose.service: nginx
strategy:
type: Recreate
template:
metadata:
annotations:
kompose.cmd: kompose convert -f ../docker-compose.yml
kompose.version: 1.22.0 (955b78124)
creationTimestamp: null
labels:
io.kompose.service: nginx
spec:
containers:
- image: myDockerHubRegistry/symfony-nginx:0.2
name: nginx
ports:
- containerPort: 80
resources: {}
volumeMounts:
- mountPath: /app/public
name: nginx-claim
restartPolicy: Always
volumes:
- name: nginx-claim
persistentVolumeClaim:
claimName: nginx-claim
status: {}
I also tried to put nginx and php-fpm on the same deployment, but I still get the same error.
What am I missing?
There are 2 issues here:
The hostname php-fpm doesn't resolve to the service's IP via DNS in k8s
nginx/openresty refuses to start if a hostname used in a proxy pass can't be resolved
nginx: [emerg] host not found in upstream "hostname"
SOLUTION:
Use a hostname that resolves correctly inside kubernetes.
The DNS scheme used by Core DNS in GKE is <service>.<namespace>.svc.cluster.local
Store the correct hostname for the php-fpm service in a variable first.
Then use this variable as the target of the the (fastcgi-)proxy pass.
This will make nginx start regardless of being able to resolve the target hostname.
Example:
set $upstream php-fpm.your-namespace.svc.cluster.local:9000;
fastcgi_pass $upstream;
Since nginx refuses to start if any proxy_pass service is not already available, you need to start the php-fpm service first. You haven't shared the deployment yaml for php-fpm. Along with the kubernetes deployment for php-fpm, you need to create a kubernetes service object for php-fpm with the name php-fpm within the same namespace as nginx.
You could also use the variable hack suggested by Nicolai so that you can start nginx without any dependency on php-fpm. But either case you need to create the kubernetes deployment and service objects for php-fpm for your application to actually work.

Docker-compose Nginx php-fpm file not found

I have a simple docker-compose config with php-fpm and nginx, and I can't see any php file. When I go to localhost, it shows File Not Found.
I tried everything I could find on the net, but everything I have tried has failed.
It works fine for html, but not for php files. Seems to be a path issue, or something like that.
I come across this error when I docker-compose logs:
project3-php_1 | 172.17.0.5 - 29/Mar/2016:13:29:12 +0000 "GET /index.php" 404
project3-front_1 | 172.17.0.1 - - [29/Mar/2016:13:29:12 +0000] "GET / HTTP/1.1" 404 27 "-" "Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/48.0.2564.116 Safari/537.36"
project3-front_1 | 2016/03/29 13:29:12 [error] 8#8: *3 FastCGI sent in stderr: "Primary script unknown" while reading response header from upstream, client: 172.17.0.1, server: localhost, request: "GET / HTTP/1.1", upstream: "fastcgi://172.17.0.2:9000", host: "localhost"
Here's my docker-compose:
project3-front:
image: nginx
ports:
- "80:80"
links:
- "project3-php:project3-php"
volumes:
- ".:/home/docker"
- "./nginxdir/default.conf:/etc/nginx/conf.d/default.conf"
- "./html:/usr/share/nginx/html"
project3-php:
build: phpdir
volumes:
- ".:/home/docker:rw"
- "./html:/var/www/html"
ports:
- "9000:9000"
working_dir: "/home/docker"
Then my dockerfile for php:
FROM php:5.6-fpm
EXPOSE 9000
my default.conf for nginx:
server {
listen 80;
server_name localhost;
index index.php index.html;
error_log /var/log/nginx/error.log warn;
access_log /var/log/nginx/access.log;
root /usr/share/nginx/html;
location ~ \.php$ {
fastcgi_pass project3-php:9000;
fastcgi_index index.php;
include fastcgi_params;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
}
}
pwd of the main folder is:
/media/revenge/share/PROJECTS/docker_images/php7-nginx
The file hierarchy is:
├── docker-compose.yml
├── html
│   ├── index.php
├── nginxdir
│   ├── default.conf
├── phpdir
│   ├── dockerfile
│   └── php.ini
The whole folder is chmod 777
Any idea would be greatly appreciated. I'm sure there is something I didn't get. Thanks in advance.
Here is how you can find the problem
Switch on the nginx debug mode with custom command, eg:
docker-compose.yml
web:
image: nginx
volumes:
- "~/www/project:/var/www"
- "~/www/project/vhost.conf:/etc/nginx/conf.d/site.conf"
# Add this row:
command: [nginx-debug, '-g', 'daemon off;']
Edit your "site.conf" file (in this example it is the ~/www/project/vhost.conf file) Switch on the debug mode by the error_log (add "debug" word at the end):
error_log "/var/log/nginx/error.log" debug;
(Re)start the "web" container:
docker-compose stop web
docker-compose up -d web
Test the containers, are all containers running?
docker-compose ps
Test in browser
"Connect" and view or download ( http://blog.dcycle.com/blog/ae67284c/docker-compose-cp ) and view the /var/log/nginx/error.log file.
The problem in the most of case
You haven't set yet or you are using different directory structure in web and php-fpm. If you want to use different structure than you have to set the "fpm structure" at the fastcgi_param SCRIPT_FILENAME place, like this:
If your docker-compose.yml contains like this:
phpfpm:
image: php:fpm
volumes:
- "~/www/project:/var/www/html/user/project"
# ^^^^^^^^^^^^^^^^^^^^^^^^^^ the path in the php-fpm container
You have to set this in "site.conf" in nginx container:
fastcgi_param SCRIPT_FILENAME /var/www/html/user/project$fastcgi_script_name;
# ^^^^^^^^^^^^^^^^^^^^^^^^^^
Finally found it:
I was missing this line in the volume of PHP section of docker-compose:
"./html:/usr/share/nginx/html"
here's what the docker-compose should look like:
project3-front:
image: nginx
ports:
- "80:80"
links:
- "project3-php:project3-php"
volumes:
- ".:/home/docker"
- "./nginxdir/default.conf:/etc/nginx/conf.d/default.conf"
- "./html:/usr/share/nginx/html"
project3-php:
build: phpdir
volumes:
- ".:/home/docker:rw"
- "./html:/var/www/html"
ports:
- "9000:9000"
working_dir: "/home/docker"
The absolute root (here "/usr/share/nginx/html") in the nginx default.conf file had to be set as well in the php part of docker-compose (was only under nginx before)
That's a relief ;)
In my case the volumes: of php and nginx were pointing a the correct (and hence the same) directory. But in my nginx config there was a NGINX_SERVER_ROOT: pointing the wrong way.
So make sure you double check all volumes and root directory settings. Some are easy to overlook.
While replacing $document_root$fastcgi_script_name; by /var/www/html/user/project$fastcgi_script_name; might fix the issue, the more elegant approach in my opinion would be just changing the nginx root directory in the default.conf:
server {
listen 80;
server_name localhost;
index index.php index.html;
error_log /var/log/nginx/error.log warn;
access_log /var/log/nginx/access.log;
root /var/www/html;
location ~ \.php$ {
fastcgi_pass project3-php:9000;
fastcgi_index index.php;
include fastcgi_params;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
}
}
And in docker-compose.yml:
project3-front:
image: nginx
ports:
- "80:80"
links:
- "project3-php:project3-php"
volumes:
- ".:/home/docker"
- "./nginxdir/default.conf:/etc/nginx/conf.d/default.conf"
- "./html:/var/www/html"
I had the same problem but this wasn't solved by any of this answer here:
Yesterday a Docker Update hits in - which has been installed. The problem depending on this update is, that the (vEthernet (DockerNAT)) Network has been changed. In that way my firewall (in my case Kaspersky) reset my network firewall to "public" instead of "trustable".
I figured this out by open "Docker -> Settings -> Shared Devices". On the first look, everthing seems fine. There was a "tick" on each device I need to be shared. Next I tried to disable and enable my shared devices again. By enable my shared device again the default error "A firewall is blocking file Sharing between Windows and the containers. See documetation for more info." came up. -> PERFECT!!. The shared device is not able to access the files anymore but Docker persists in the state that its all fine.
So I could fix it by:
Set (vEthernet (DockerNAT)) Network as trusted again in my Kaspersky "Firewall - Network" settings.
Restarted my docker container by using docker-compose up and everthing runs like a charm. My files could be accessed again.
One of the case might be, Your running the docker container and did composer install/update
then run following to restart container
`docker-compose down` `docker-compose up -d`

Categories