I have prepared a docker environment to run certain PHP based websites using nginx reverse proxy. Things mostly work except for one glitch. The URLs return the output of index.php just fine without mentioning index.php http://web.local/web, however, when I do it like http://web.local/web/index.php or any .php file for that matter.
web container gives the following error.
2021/10/24 11:18:19 [error] 28#28: *3 FastCGI sent in stderr: "Primary script unknown" while reading response header from upstream, client: 192.168.224.6, server: proxy, request: "GET /web/index.php HTTP/1.0", upstream: "fastcgi://192.168.224.4:9000", host: "web.local"
and nginx container gives following error.
192.168.224.1 - - [24/Oct/2021:11:18:19 +0000] "GET /web/index.php HTTP/1.1" 404 27 "-" "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/94.0.4606.81 Safari/537.36"
I've tried to search previous posts of this FastCGI sent in stderr error but nothing matches my problem.
Possible issues seem to be difference in users. NGINX proxy container uses root whereas PHP-FPM container uses www-data. Below are my configuration files.
NGINX (proxy) nginx.conf
user root;
worker_processes auto;
pid /run/nginx.pid;
include /etc/nginx/modules-enabled/*.conf;
events {
worker_connections 1024;
}
http {
upstream nginx-web {
server web:8110;
}
upstream nginx-portal {
server portal:8115;
}
upstream nginx-api {
server api:8120;
}
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Host $server_name;
server {
listen 80;
server_name proxy;
location /web {
proxy_pass http://nginx-web;
}
location /portal {
proxy_pass http://nginx-portal;
}
location /api {
proxy_pass http://nginx-api;
}
}
}
Server block (web) default.conf
server {
listen 8110;
root /var/www/web;
server_name proxy;
location / {
try_files $uri $uri/ /index.php$is_args$args;
index index.php;
}
location ~ ^/.+\.php(/|$) {
fastcgi_pass php:9000;
fastcgi_index index.php;
include fastcgi_params;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
}
}
docker-compose.yml
version: "3.9"
services:
db:
container_name: db
image: mysql:5.7
ports:
- "3306:3306"
volumes:
- "${PROJECT_ROOT}/db:/var/lib/mysql"
- ./conf/db/my.cnf:/etc/mysql/conf.d/my.cnf:ro
env_file:
- .env
networks:
- backend
proxy:
container_name: proxy
image: nginx:mainline-alpine
volumes:
- ./conf/proxy/nginx.conf:/etc/nginx/nginx.conf:ro
ports:
- "80:80"
- "8110:8110"
- "8115:8115"
- "8120:8120"
depends_on:
- web
- portal
- api
networks:
- backend
web:
container_name: web
image: nginx:mainline-alpine
volumes:
- "${PROJECT_ROOT}/web:/var/www/web"
- ./conf/web/default.conf:/etc/nginx/conf.d/default.conf:ro
depends_on:
- php
networks:
- backend
portal:
container_name: portal
image: nginx:mainline-alpine
volumes:
- "${PROJECT_ROOT}/portal:/var/www/portal"
- ./conf/portal/default.conf:/etc/nginx/conf.d/default.conf:ro
depends_on:
- db
- php
networks:
- backend
api:
container_name: api
image: nginx:mainline-alpine
volumes:
- "${PROJECT_ROOT}/api:/var/www/api"
- ./conf/api/default.conf:/etc/nginx/conf.d/default.conf:ro
depends_on:
- php
networks:
- backend
php:
container_name: php
image: maciejslawik/php-fpm-xdebug:latest
ports:
- "9000:9000"
volumes:
- "${PROJECT_ROOT}/web:/var/www/web"
- "${PROJECT_ROOT}/portal:/var/www/portal"
- "${PROJECT_ROOT}/api:/var/www/api"
- ./conf/php/docker-php-ext-xdebug.ini:/usr/local/etc/php/conf.d/docker-php-ext-xdebug.ini:ro
networks:
- backend
composer:
container_name: composer
image: composer:2
restart: "no"
command: install
volumes:
- "${PROJECT_ROOT}/composer:/app"
- ./composer/composer.json:/app/composer.json
networks:
- backend
phinx:
container_name: phinx
image: vegbrasil/phinx:latest
volumes:
- "${PROJECT_ROOT}/migrations/database/migrations:/app/database/migrations"
- "${PROJECT_ROOT}/migrations/database/seeds:/app/database/seeds"
- ./conf/phinx/phinx.php:/app/phinx.php:ro
env_file:
- .env
depends_on:
- db
restart: "no"
command: "status"
environment:
- TESTS_PHINX_DB_ADAPTER_MYSQL_HOST=db
networks:
- backend
schemaspy:
container_name: schemaspy
image: schemaspy/schemaspy:latest
volumes:
- "${PROJECT_ROOT}/schemaspy/output:/output"
- ./conf/schemaspy/schemaspy.properties:/schemaspy.properties:ro
restart: "no"
depends_on:
- db
networks:
- backend
networks:
backend:
I've tried to check the output of return 200 $document_root$fastcgi_script_name; and it returns correct values.
The default PHP-FPM user www-data doesn't have permission to chmod or chcon any file or directory.
$_SERVER vardump
array (size=53)
'PHP_EXTRA_CONFIGURE_ARGS' => string '--enable-fpm --with-fpm-user=www-data --with-fpm-group=www-data --disable-cgi' (length=77)
'HOSTNAME' => string '4b4c2f5dcdb7' (length=12)
'PHP_INI_DIR' => string '/usr/local/etc/php' (length=18)
'HOME' => string '/var/www' (length=8)
'PHP_LDFLAGS' => string '-Wl,-O1 -Wl,--hash-style=both -pie' (length=34)
'PHP_CFLAGS' => string '-fstack-protector-strong -fpic -fpie -O2 -D_LARGEFILE_SOURCE -D_FILE_OFFSET_BITS=64' (length=83)
'PHP_MD5' => string '' (length=0)
'PHP_VERSION' => string '7.4.0' (length=5)
'GPG_KEYS' => string '42670A7FE4D0441C8E4632349E4FDC074A4EF02D 5A52880781F755608BF815FC910DEB46F53EA312' (length=81)
'PHP_CPPFLAGS' => string '-fstack-protector-strong -fpic -fpie -O2 -D_LARGEFILE_SOURCE -D_FILE_OFFSET_BITS=64' (length=83)
'PHP_ASC_URL' => string 'https://www.php.net/get/php-7.4.0.tar.xz.asc/from/this/mirror' (length=61)
'PHP_URL' => string 'https://www.php.net/get/php-7.4.0.tar.xz/from/this/mirror' (length=57)
'PATH' => string '/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin' (length=60)
'PHPIZE_DEPS' => string 'autoconf dpkg-dev file g++ gcc libc-dev make pkg-config re2c' (length=76)
'PWD' => string '/var/www/html' (length=13)
'PHP_SHA256' => string '9bb751b20e5d6cc1ea9b1ebf23ef2d5f07f99b2d9cc417bf1d70c04f8b20ec42' (length=64)
'USER' => string 'www-data' (length=8)
'HTTP_ACCEPT_LANGUAGE' => string 'en-US,en;q=0.9,ur;q=0.8' (length=23)
'HTTP_ACCEPT_ENCODING' => string 'gzip, deflate' (length=13)
'HTTP_ACCEPT' => string 'text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.9' (length=135)
'HTTP_USER_AGENT' => string 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/94.0.4606.81 Safari/537.36' (length=114)
'HTTP_UPGRADE_INSECURE_REQUESTS' => string '1' (length=1)
'HTTP_CACHE_CONTROL' => string 'max-age=0' (length=9)
'HTTP_CONNECTION' => string 'close' (length=5)
'HTTP_X_FORWARDED_HOST' => string 'proxy' (length=5)
'HTTP_X_FORWARDED_FOR' => string '192.168.224.1' (length=13)
'HTTP_X_REAL_IP' => string '192.168.224.1' (length=13)
'HTTP_HOST' => string 'web.local' (length=9)
'SCRIPT_FILENAME' => string '/var/www/web/index.php' (length=22)
'REDIRECT_STATUS' => string '200' (length=3)
'SERVER_NAME' => string 'proxy' (length=5)
'SERVER_PORT' => string '8110' (length=4)
'SERVER_ADDR' => string '192.168.224.7' (length=13)
'REMOTE_PORT' => string '54314' (length=5)
'REMOTE_ADDR' => string '192.168.224.6' (length=13)
'SERVER_SOFTWARE' => string 'nginx/1.21.3' (length=12)
'GATEWAY_INTERFACE' => string 'CGI/1.1' (length=7)
'REQUEST_SCHEME' => string 'http' (length=4)
'SERVER_PROTOCOL' => string 'HTTP/1.0' (length=8)
'DOCUMENT_ROOT' => string '/var/www/web' (length=12)
'DOCUMENT_URI' => string '/index.php' (length=10)
'REQUEST_URI' => string '/web/' (length=5)
'SCRIPT_NAME' => string '/index.php' (length=10)
'CONTENT_LENGTH' => string '' (length=0)
'CONTENT_TYPE' => string '' (length=0)
'REQUEST_METHOD' => string 'GET' (length=3)
'QUERY_STRING' => string '' (length=0)
'FCGI_ROLE' => string 'RESPONDER' (length=9)
'PHP_SELF' => string '/index.php' (length=10)
'REQUEST_TIME_FLOAT' => float 1635101620.5358
'REQUEST_TIME' => int 1635101620
'argv' =>
array (size=0)
empty
'argc' => int 0
Update: I've changed the server > location block for php as below.
location ~ ^/.+\.php(/|$) {
return 200 $document_root$fastcgi_script_name;
fastcgi_pass php:9000;
# fastcgi_index index.php;
include fastcgi_params;
# fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
fastcgi_param SCRIPT_FILENAME /var/www/web/help.php;
}
Result: Even though I open the URL http://web.local/web/help.php, it downloads a file with content /var/www/web/index.php. With hardcoded SCRIPT_FILENAME it shows me the output of correct file i.e. help.php so doesn't look like a permission issue as I had felt earlier. I notice that fastcgi_index is also irrelevant.
Question: Where is the value of $document_root$fastcgi_script_name coming from?