我在 Docker 容器中拥有以下 NGINX (1.13) 配置,它充当前端和后端的伞式代理。服务器backend
是 PHP-FPM 容器,frontend
是一个 NodeJS/React 应用程序。
http://example.com/.*
我希望前端捕获域名 URL并将http://example.com/api/.*
其传送到backend
。无论我尝试什么似乎都不起作用,所有 API 调用都以 404 结束并由 处理frontend
。
upstream api_cluster {
server backend:8999;
}
server {
listen 80;
server_name localhost;
root /var/www/html;
location ~* ^/api/ {
# handle OPTIONS requests
# @note: don't try to DRY out this "if" block, or you're gonna have a bad time.
# @see: http://wiki.nginx.org/IfIsEvil
if ($request_method = 'OPTIONS') {
add_header 'Access-Control-Allow-Credentials' 'true';
add_header 'Access-Control-Allow-Headers' 'Authorization,Content-Type,Accept,Origin,User-Agent,DNT,Cache-Control,X-Mx-ReqToken,Keep-Alive,X-Requested-With,If-Modified-Since';
add_header 'Access-Control-Allow-Methods' 'GET, DELETE, OPTIONS, POST, PUT';
add_header 'Access-Control-Allow-Origin' '*';
add_header 'Access-Control-Max-Age' 2592000;
add_header 'Content-Length' 0;
add_header 'Content-Type' 'text/plain charset=UTF-8';
return 204;
}
fastcgi_split_path_info ^(.+?\.php)(/.*)$;
rewrite ^/(.*)/$ /$1 permanent;
try_files $uri $uri/ /index.php?$args;
# send the CORS headers
add_header 'Access-Control-Allow-Credentials' 'true';
add_header 'Access-Control-Allow-Origin' '*';
# set additional security headers
add_header 'Cache-Control' 'no-cache, no-store, must-revalidate';
#add_header 'Content-Security-Policy' 'connect-src *';
add_header 'Expires' '0';
add_header 'Pragma' 'no-cache';
add_header 'Strict-Transport-Security' 'max-age=31536000; includeSubDomains';
add_header 'X-Content-Type-Options' 'nosniff';
add_header 'X-Frame-Options' 'DENY';
add_header 'X-XSS-Protection' '1; mode=block';
include fastcgi_params;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
fastcgi_param SCRIPT_NAME $fastcgi_script_name;
fastcgi_param PATH_INFO $fastcgi_path_info;
fastcgi_param AUTHORIZATION $http_authorization;
# Mitigate https://httpoxy.org/ vulnerabilities
fastcgi_param HTTP_PROXY "";
fastcgi_index index.php;
fastcgi_pass api_cluster;
}
location / {
proxy_pass http://frontend:3000;
proxy_http_version 1.1;
proxy_set_header X-Forwarded-Proto $scheme;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection 'upgrade';
proxy_set_header Host $host;
proxy_cache_bypass $http_upgrade;
}
}
答案1
您应该将其用作location /api
块指令,因为您想要一个简单的前缀匹配。
如果更改这没有帮助,您需要通过运行来验证 nginx 是否实际使用了您创建的配置nginx -T
,这将显示 nginx 从配置文件中解析的配置。
答案2
罪魁祸首是一行try_files $uri $uri/ /index.php?$args;
内部重定向到/index.php?$args;
,它将匹配location /
。
我应该感谢 NGINX IRC 频道上的用户xavierg
,他启发了我并解决了这个问题。