Nginx重写到根目录下的子文件夹

docker运行在后端专用networking中,我有一些微服务,并且想要build立一个由nginxpipe理的dynamic路由,以便它可以select基于URI的微服务。 我有三个问题:

  1. 我需要nginx从URI中path的第一部分获取fastcgi_pass指令的域名,所以从语句fastcgi_pass app:9000; “app” fastcgi_pass app:9000; 应该从这里来: https://example.com/app/foo/barhttps://example.com/app/foo/bar 。 如果URI中的URI是https://example.com/another-app/foo/bar ,则该指令看起来像fastcgi_pass another-app:9000; 是否可以dynamic地这样做,或者我将不得不为每个FastCGI服务器创build一个单独的位置?

  2. 我也需要它根据相同的第一个URIpath段重写到根目录下的一个文件夹。 我写了一个configuration,但得到404错误。 我是nginx的新手,只注意到nginx和php-fpm容器中的path不匹配。 404错误可以与这个事实相关吗?

  3. 这种路由是否可能(详情请参阅下面的configuration)? 另一个select是为每个微服务创build一个单独的位置,但我不想每次添加或删除微服务时都要更改此configuration。

这是我的configuration:

 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; } 

我想出了以下nginxconfiguration,允许将请求路由到不同的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容器中的绝对path和应用程序的容器不匹配,因此它使用fastcgi参数映射。