I've got 2 AWS EC2 instances, one of which resides in a public subnet and is configured to act as a NAT instance, and runs Nginx. The other instance resides in a private subnet, but can communicate with the public one. The respective IP addresses of the instances are, for example:
- 172.25.48.14 - Nginx instance in a public subnet (172.25.48.0/28), has an Elastic IP assigned
- 172.25.48.140 - instance running php-fpm in a private subnet (172.25.48.128/28)
The thing is, I want this website to be accessible by a certain URL - I supposed Nginx to act as a reverse proxy server which maps requests to certain subdomains or URLs to respective resources. So, here is my Nginx configuration:
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;
}
}
}
}
And here is, respectively, the php-fpm pool configuration for the site in the private instance:
[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%%"
For the sake of simplicity let's assume I have only a single index.php
file, which resides in the private instance as well at /apps/site1/
, which has a symlink at /var/www/html/site1
.
The problem is that no matter what I try, I get 404, and judging by the logs on the private instance side, the request doesn't even get there - even though I know I have the instance security groups configured properly and on the right ports, because otherwise I can connect from the private instance to the public one and vice versa without any problems. The only time I got a request through to the php-fpm (albeit a 404 as well) was when I moved the deep-most "location" lookup (the one that matches for the .php scripts) to the server top level - so basically the request went straight to 172.25.48.14
, and not to 172.25.48.14/site1
as I intended.
Am I missing something? Could the issue be that the source files are located on the same instance as php-fpm, and not on the Nginx side? Am I getting the concept of how it works wrong? Please, if you have any ideas on this, I'll be extremely grateful for your help. Thanks in advance!
Your config, being tested with
nginx -t
command, should give you an error message likedue to the
line. If it was supposed to be the
directive, it also won't work. This directive makes nginx checking your request URI to be a physical file relative to your web server root (which isn't defined at all), obviously failing (since your PHP file is located at the other host). This line should be removed from your nested location.
Since you didn't explicitly define your website root, by default it is equal to
{prefix}/html
where{prefix}
is some precompiled value (can be viewed usingnginx -V
command). So whatever you passing to your private instance via thedirective, most likely it isn't correct one. You should use either
or
within your nested location (although I don't know how PHP-FPM will treat the paths with symlinks included).
As already being said at StackOverflow:
Add either
or
to your parent location.
You don't need to use both
and
in your nested location. They are almost the same, the only difference is that
fastcgi.conf
file includes theline while
fastcgi_params
doesn't (when using thefastcgi_params
file rather thanfastcgi.conf
, you should include this line yourself).Any
PATH_INFO
related stuff such asmakes no sense at the
location ~ \.php$ { ... }
locations (in opposite tolocation ~ \.php(?:/|$) { ... }
ones).Why do not use a simply prefix location like
or
(especially sinсe you don't make use of the regex capture group anyway)?