我有 2 个 AWS EC2 实例,其中一个位于公共子网中,配置为充当NAT 实例,并运行 Nginx。另一个实例位于私有子网中,但可以与公共子网通信。实例的相应 IP 地址如下:
- 172.25.48.14 - 公共子网 (172.25.48.0/28) 中的 Nginx 实例,已分配弹性 IP
- 172.25.48.140 - 在私有子网中运行 php-fpm 的实例(172.25.48.128/28)
问题是,我希望该网站可以通过某个 URL 访问 - 我假设 Nginx 充当反向代理服务器,将请求映射到某些子域或 URL 到相应的资源。因此,这是我的 Nginx 配置:
http {
sendfile on;
tcp_nopush on;
types_hash_max_size 2048;
server_names_hash_bucket_size 128;
include /etc/nginx/mime.types;
default_type text/html;
proxy_headers_hash_bucket_size;
access_log /var/log/nginx/access.log
error_log /var/log/nginx/error.log
server {
listen 80;
location ~ ^/site1(.*)$ {
# These are commented out because no matter if specified or not the result is the same
# index index.php;
# try_files $uri $uri/ /site1/index.php?$request_uri;
location ~ \.php$ {
include fastcgi.conf;
try $uri =404;
fastcgi_split_path_info ^(.+\.php)(/.+)$;
fastcgi_pass 172.25.48.140:9000;
fastcgi_index index.php;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
include fastcgi_params;
}
}
}
}
以下是私有实例中站点的 php-fpm 池配置:
[site1]
user = www-data
group = www-data
listen = 172.25.48.140:9000
listen.allowed_clients = 172.25.48.14, 172.25.48.140, 127.0.0.1
php_admin_value[disable_functions] = exec, passthru, shell_exec, system
php_admin_flag[allow_url_fopen] = off
pm = dynamic
pm.max_children = 10
pm.start_servers = 1
pm.min_spare_servers = 1
pm.max_spare_servers = 8
pm.process_idle_timeout = 30s
pm.status_path = /php_status
ping.path = /ping
ping.response = wrrrrrrrrryyyyyyyyyyy
access.log = /var/log/php/8.3/$pool.access.log
access.format = "%R - %u %t \"%m %r%Q%q\" %s %f %{milli}d %{kilo}M %C%%"
为了简单起见,我们假设我只有一个index.php
文件,该文件也位于 的私有实例中/apps/site1/
,并且有一个位于 的符号链接/var/www/html/site1
。
问题是无论我怎么尝试,我都会得到 404,并且根据私有实例端的日志判断,请求甚至没有到达那里 - 即使我知道我已正确配置了实例安全组并在正确的端口上,因为否则我可以从私有实例连接到公共实例,反之亦然,没有任何问题。我唯一一次通过 php-fpm 收到请求(尽管也是 404)是当我将最深的“位置”查找(与 .php 脚本匹配的查找)移动到服务器顶层时 - 所以基本上请求直接转到172.25.48.14
,而不是172.25.48.14/site1
我预期的那样。
我是不是漏掉了什么?问题可能是源文件与 php-fpm 位于同一实例上,而不是 Nginx 端?我是否误解了它的工作原理?如果您对此有任何想法,我将非常感谢您的帮助。提前致谢!
您的配置正在使用
nginx -t
命令进行测试,应该会给出类似这样的错误消息由于
线。如果它应该是
指令,它也不会起作用。此指令使 nginx 检查您的请求 URI 是否是相对于您的 Web 服务器根目录(根本没有定义)的物理文件,这显然会失败(因为您的 PHP 文件位于其他主机)。应从嵌套位置中删除此行。
由于您没有明确定义您的网站根目录,默认情况下它等于
{prefix}/html
某个{prefix}
预编译值(可以使用nginx -V
命令查看)。因此,无论您通过指令,很可能它不正确。您应该使用
或者
在嵌套位置内(虽然我不知道 PHP-FPM 将如何处理包含符号链接的路径)。
正如StackOverflow 上所说的那样:
添加
或者
到您的父级位置。
你不需要同时使用
和
在您的嵌套位置。它们几乎相同,唯一的区别是
fastcgi.conf
文件包含行而
fastcgi_params
没有(当使用fastcgi_params
文件而不是时fastcgi.conf
,您应该自己包含此行)。任何
PATH_INFO
相关的东西,例如location ~ \.php$ { ... }
在位置上(与位置相反)没有意义location ~ \.php(?:/|$) { ... }
。为什么不使用简单的前缀位置,例如
或者
(特别是因为你无论如何都不使用正则表达式捕获组)?