[英]Nginx rewrite to subfolder under root
我有一些由docker管理的微服务在后端专用网络中运行,并且想要设置一个由nginx管理的动态路由,以便它可以基于URI选择微服务。 我有三个问题:
我需要nginx从URI路径的第一段中获取fastcgi_pass
指令的域名,因此从语句fastcgi_pass app:9000;
“ app” fastcgi_pass app:9000;
应该来自这里: https://example.com/app/foo/bar
: https://example.com/app/foo/bar
。 如果URI是URI中的https://example.com/another-app/foo/bar
,则该指令将类似于fastcgi_pass another-app:9000;
是否可以通过这种方式动态地实现,还是必须为每个FastCGI服务器创建一个单独的位置?
我还需要它来重写根目录下的文件夹,具体取决于相同的第一个URI路径的段。 我写了一个配置,但收到404错误。 我是nginx的新手,只是注意到nginx和php-fpm容器中的路径不匹配。 404错误可以与此事实相关吗?
这种路由完全可行吗(有关更多详细信息,请参见下面的配置)? 另一个选择是为每个微服务创建一个单独的位置,但是我不想每次添加或删除微服务时都更改此配置。
这是我的配置:
server {
server_name _;
root /services;
#rewrite to the subfolder under root depending on the first section in the path
rewrite ^/(\w+)(/|$) /$1/app_dev.php$is_args$args last;
location / {
# try to serve file directly, fallback to app.php
try_files $uri /app_dev.php$is_args$args;
}
location ~ ^/(\w+)/(app_dev|config)\.php(/|$) {
#further rewrite to the /web subfolder with the front controller
rewrite ^/(\w+)/(app_dev|config)\.php(/|$) /$1/web/$2.php$is_args$args break;
fastcgi_pass media:9000;
fastcgi_split_path_info ^(.+\.php)(/.*)$;
include fastcgi_params;
fastcgi_param SCRIPT_FILENAME $realpath_root$fastcgi_script_name;
fastcgi_param DOCUMENT_ROOT $realpath_root;
}
location ~ \.php$ {
return 404;
}
error_log /var/log/nginx/error.log notice;
access_log /var/log/nginx/access.log;
rewrite_log on;
}
这是日志:
backend_1 | 2017/09/17 20:03:54 [error] 8#8: *1 open() "/usr/share/nginx/html/media" failed (2: No such file or directory), client: 172.25.0.1, server: localhost, request: "GET /media HTTP/1.1", host: "localhost:8082"
backend_1 | 172.25.0.1 - - [17/Sep/2017:20:03:54 +0000] "GET /media HTTP/1.1" 404 571 "-" "Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/61.0.3163.79 Safari/537.36" "-"
还有一个问题是,我看不到任何重写日志,猜测它可能与两个位置都不匹配的事实有关。
因此这可能在单个位置块中
location ~ ^/(?P<app>\w+)/(app_dev|config)\.php(/|$) {
#further rewrite to the /web subfolder with the front controller
rewrite ^/(\w+)/(app_dev|config)\.php(/|$) /$1/web/$2.php$is_args$args break;
fastcgi_pass $app:9000;
fastcgi_split_path_info ^(.+\.php)(/.*)$;
include fastcgi_params;
fastcgi_param SCRIPT_FILENAME $realpath_root$fastcgi_script_name;
fastcgi_param DOCUMENT_ROOT $realpath_root;
}
我想出了以下nginx配置,允许将请求路由到不同docker容器中的应用。 感谢@TarunLalwani的提示:
server {
server_name _;
location ~ ^/(?P<service>\w+)(/|$) {
root /services/$service/web;
rewrite ^ /app_dev.php$is_args$args break;
resolver 127.0.0.11;
fastcgi_pass $service:9000;
fastcgi_split_path_info ^(.+\.php)(/.*)$;
include fastcgi_params;
fastcgi_param SCRIPT_FILENAME /app/web/app_dev.php;
fastcgi_param DOCUMENT_ROOT /app/web;
}
location ~ \.php$ {
return 404;
}
error_log /var/log/nginx/error.log debug;
access_log /var/log/nginx/access.log;
rewrite_log on;
}
应用程序路由还需要一个与微服务名称匹配的前缀,我已将其添加到文件app/config/routing.yml
(我正在使用Symfony):
app:
resource: '@AppBundle/Controller/'
type: annotation
prefix: /media
微服务的代码从应用程序的容器安装到/ services目录下的nginx容器。 nginx容器和应用程序容器中的绝对路径不匹配,因此使用fastcgi参数对其进行映射。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.