我想将任何api/*
路由传递给 php-fpm。具体来说,index.php
因为我使用 Symfony。这是唯一应该使用 php 的路由。其他任何内容都将从中加载/usr/share/nginx/html/public
(仅 HTML 文件和 CSS)。
我尝试过这个,但是出现了错误:
FastCGI sent in stderr: "Primary script unknown" while reading response header from upstream
我的 nginx 配置如下:
upstream php {
server php:9000;
}
server {
listen 80 default_server;
server_name impressive.local;
index index.html index.php;
root /usr/share/nginx/html/public;
location /api {
root /usr/share/nginx/html/api;
try_files $uri /index.php;
}
location ~ \.php$ {
fastcgi_pass php;
fastcgi_split_path_info ^(.+\.php)(/.*)$;
include fastcgi.conf;
}
}
我收到以下错误:
php_1 | [13-Jan-2019 23:22:54] NOTICE: fpm is running, pid 1
php_1 | [13-Jan-2019 23:22:54] NOTICE: ready to handle connections
php_1 | 172.25.0.3 - 13/Jan/2019:23:22:57 +0000 "GET /api/index.php" 404
web_1 | 2019/01/13 23:22:57 [error] 10#10: *1 FastCGI sent in stderr: "Primary script unknown" while reading response header from upstream,
client: 172.25.0.1, server: impressive.local, request: "GET /api/index.php HTTP/1.1", upstream: "fastcgi://172.25.0.2:9000", host: "127.0.0.1:8080"
web_1 | 172.25.0.1 - - [13/Jan/2019:23:22:57 +0000] "GET /api/index.php HTTP/1.1" 404 27 "-" "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/71.0.3578.98 Safari/537.36" "-"
我在 Google 上搜索了几个小时,在 Stack Exchange 上查看了多个其他答案。我似乎无法弄清楚是什么原因造成的。我使用 docker。下面是我的docker-compose.yml
version: '3'
services:
web:
image: nginx:alpine
volumes:
- ./web:/usr/share/nginx/html
- ./conf/impressive.template:/etc/nginx/conf.d/default.conf
ports:
- "8080:80"
links:
- php
php:
image: php:7.3.1-fpm-alpine
volumes:
- ./web:/usr/share/nginx/html
/usr/share/nginx/html
结构如下:
- api
index.php
- public
index.html
something.html
...
api
是一个 JSON API,并且public
是静态站点。
我希望所有请求都可以api/*
通过电话进行api/index.php
,其他所有请求都可以通过 进行/usr/share/nginx/html/public
。
答案1
我终于解决了!
事实证明,根位置必须与 php-fpm 容器上文件的位置相匹配,因为这是通过以下方式传递的:
fastcgi_param SCRIPT_FILENAME $realpath_root$fastcgi_script_name
我不需要指定该行,因为它包含在:中include fastcgi.conf;
。
我不确定这是否是最优雅的解决方案:
upstream php {
server php:9000;
}
server {
listen 80 default_server;
server_name _;
index index.html index.php;
root /usr/share/nginx/html/public;
location /api {
root /usr/share/nginx/html;
try_files $uri /api/index.php$is_args$args;
location ~ \.php$ {
fastcgi_pass php;
fastcgi_split_path_info ^(.+\.php)(/.*)$;
include fastcgi.conf;
internal;
}
}
}
答案2
我无法添加评论,但可以回答。
如果有人遇到与 Bert 或 Ivan Fretes 相同的“问题”,请查看注释中的第 4 点:https://www.nginx.com/resources/wiki/start/topics/examples/phpfcgi
如果未设置 SCRIPT_FILENAME,则显示 200 的空白页是正常的。
如果不设置该参数,PHP FPM 会返回 200 OK,内容为空,没有错误或警告。有关 CGI 参数的更多信息,请参考 nginx 初学者指南、PHP 中的 $_SERVER 和 RFC3875。
解决方案不是将其留空,而是可以将其设置为正确的值。首先,尝试添加最有效的默认值:
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
但有时,这还不够。例如,我运行一个 wordpress-fpm 容器,它希望其文件位于 /var/www/html 中。但在我的主机上,文件位于 /opt/wordpress/wordpress_data 中。
解决方案一:将其从 /opt/... 移动到 /var/...
解决方法二:在nginx中定义root normal:
root /opt/wordpress/wordpress_data;
但通过添加/覆盖来修复 SCRIPT_FILENAME 参数:
fastcgi_param SCRIPT_FILENAME /var/www/html/$fastcgi_script_name;
(我用硬编码路径替换了变量 $document_root,文件在 fpm 容器内可见)
答案3
/
对我来说,这非常简单,我的参数在文档根定义末尾丢失,例如root /var/www;
我将其更改为 root /var/www/;
原因是SCRIPT_FILENAME
线是这样的fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
注意没有/
之间 $document_root
和$fastcgi_script_name
这是我的nginx.conf
文件中的 PHP 块
location ~ \.php$ {
root /var/www/;
fastcgi_pass unix:/run/php-fpm7/php-fpm.sock;
fastcgi_index index.php;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
include fastcgi_params;
}