Php 双nginx反向代理中请求uri的正确处理?

Php 双nginx反向代理中请求uri的正确处理?,php,nginx,docker,joomla,reverse-proxy,Php,Nginx,Docker,Joomla,Reverse Proxy,因此,基本上我在Docker php7 fpm容器中运行Joomla,然后我有一个nginx容器,其中一个Joomla.conf文件定义如下: #https://docs.joomla.org/nginx server { listen 8081; error_log /var/log/nginx/error.log; access_log /var/log/nginx/access.log; server_name php-docker.local; root /

因此,基本上我在Docker php7 fpm容器中运行Joomla,然后我有一个nginx容器,其中一个Joomla.conf文件定义如下:

#https://docs.joomla.org/nginx

server {
  listen 8081;

  error_log  /var/log/nginx/error.log;
  access_log /var/log/nginx/access.log;

  server_name php-docker.local;

  root /usr/src/joomla;
  index index.php index.html index.htm default.html default.htm;

  location / {
    try_files $uri $uri/ /index.php?$args;
  }

  # deny running scripts inside writable directories
  location ~* /(images|cache|media|logs|tmp)/.*\.(php|pl|py|jsp|asp|sh|cgi)$ {
    return 403;
    error_page 403 /403_error.html;
  }

  location ~ \.php$ {
    fastcgi_pass  joomla:9000;
    fastcgi_index index.php;
    fastcgi_split_path_info ^(.+\.php)(/.+)$;

    include fastcgi_params;
    #include /etc/nginx/fastcgi.conf;
    fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
    fastcgi_param PATH_INFO $fastcgi_path_info;
  }
}
这就像预期的一样。。。转到http://:8081将正确加载所有内容

现在,8081只是暂时暴露在nginx容器中,我主要想做的是设置一个反向代理,这样http:///joomla 将是最终终点

为此,我正在处理以下conf文件:

server{

  listen 80;
  server_name _;

  location /joomla/ {
    proxy_pass          http://localhost:8081/;

    proxy_set_header    Referer           $http_referer;
    proxy_set_header    X-Forwarded-Port  $server_port;
    proxy_set_header    X-Forwarded-Proto $http_x_forwarded_proto;
    proxy_set_header    Host              $host;
    proxy_set_header    X-Forwarded-For   $proxy_add_x_forwarded_for;
    proxy_set_header    X-Forwarded-Host  $host;
  }

}
所发生的事情是,HTML被正确地提供,但是,没有一个资产是正确的。这是因为Joomla中的URL是由一个JURI类生成的,它似乎依赖于$request_uri,当它到达Joomla时,它似乎已经丢失了

因此,对文件、脚本或css的每个链接或引用呈现如下:

而不是:

然而,当我访问第二组URL时,我可以毫无问题地访问链接/资源。。。但是,当然,没有图像、模板、js或链接被正确呈现

我不想碰joomla.conf,除非有什么不对劲,至于site.conf,我只想翻译URI段以将请求映射到其他应用程序,例如:

/joomla -> localhost:8081
/phpbb -> localhost:8082
/someapp -> localhost:8083
如上所述,您需要在
configuration.php
中配置
$live\u站点
var,如下所示:

public $live_site = '/joomla/';
我制作了一个在编辑该文件后运行良好的程序,它使用了您的配置



变成:

您可以尝试使用sub_filter,如中所述

因此,在您的情况下,nginx配置应该如下所示:

server{

  listen 80;
  server_name _;

  location /joomla/ {
    proxy_pass          http://localhost:8081/;

    proxy_set_header    Referer           $http_referer;
    proxy_set_header    X-Forwarded-Port  $server_port;
    proxy_set_header    X-Forwarded-Proto $http_x_forwarded_proto;
    proxy_set_header    Host              $host;
    proxy_set_header    X-Forwarded-For   $proxy_add_x_forwarded_for;
    proxy_set_header    X-Forwarded-Host  $host;
    sub_filter "http://your_server/" "http://your_server/joomla/";
    sub_filter_once off;
  }

}
最干净的解决方案是修改上游,为所有资源提供唯一的路径。

通常,从上游删除URL的一部分(带有唯一前缀)要比向非唯一URL添加额外部分容易得多。这是因为您总是可以捕获较长的URL并准确地知道它所指的内容,随后将301或302重定向返回到较短和更简洁的版本

另一方面,面对短请求URL,如
/
,很难确定它可能引用哪个应用程序(除非您也查看
$http\u referer
变量,然后根据URL请求的来源有条件地发出重定向),或者,除非您实现了某种意大利面条规则来检测哪些URL引用了哪些应用程序(如果您这样做,可能会派上用场)


另外,考虑到安全性,当Cookie参与时,在单个域上运行多个独立的应用程序不是最好的做法。一个应用程序中的折衷很容易导致所有其他应用程序中的安全违规。

< P>我知道这是旧的,但这是我的答案。您不应该更改
configuration.php
文件,基本上是因为您应该将您的服务(web和代理)完全分离(服务实现产生的问题应该在该服务中解决),这将使您的服务体系结构更加灵活。 更改以下代理设置时,必须过滤资源URL和一些
位置
标题

server {
    #... other settings

    location /joomla/ {
        # Main redirect
        proxy_pass http://joomla_service/;

        # Set the Host Header
        proxy_set_header Host $host;

        # When Joomla redirects a Location Header
        # For example when you log in, Joomla retrieves you a response with a Location Header = localhost
        # we don't want this.
        proxy_redirect http://localhost/ http://localhost/joomla/;
        proxy_redirect / /joomla/;

        # Some content rewriting
        sub_filter_types text/javascript application/javascript;

        # Html redirection
        sub_filter '="/' '="/joomla/';
        sub_filter '="http://localhost/' '="/joomla/';
        sub_filter '\'http://localhost/administrator/' '\'/joomla/administrator/';
        sub_filter 'url(\'/media' 'url(\'/joomla/media';

        # Some json data
        sub_filter '"root":""' '"root":"\/joomla"';
        sub_filter '"uri":"\/index.php' '"uri":"\/joomla\/index.php';
        sub_filter '"jdragdrop":"\/media' '"jdragdrop":"\/joomla\/media';
        sub_filter '"plg_quickicon_privacycheck_url":"http:\/\/localhost' '"plg_quickicon_privacycheck_url":"\/joomla';
        sub_filter '"plg_quickicon_privacycheck_ajax_url":"http:\/\/localhost' '"plg_quickicon_privacycheck_ajax_url":"\/joomla';
        sub_filter '"content_css":"\/templates' '"content_css":"\/joomla\/templates';

        sub_filter_once off;
    }
}

出于某种原因,如果我们讨论实现反向代理,Joomla并没有提供很好的支持。我创建了一个包含更多详细信息的示例,您可以看到它。

您是否尝试过从浏览器中以这种方式访问<代码>http:///joomla/(结尾为/)。您的nginx配置不会影响Joomla生成链接的方式。如果面向nginx的客户端只将
/joomla/
转发到上游的joomla nginx,那么它将永远不会传递
/images/headers/maple.jpg
/login
。如果您总是在面向nginx的客户端上通过
/Joomla/
访问Joomla,那么您唯一的选择就是更改Joomla配置。您已尝试更改Joomla配置文件中的$live_site参数?OP,您是否愿意查看答案并奖励奖金?如果你不采取行动,至少一半的赏金将被浪费。谢谢另外,如果你决定选择推荐人路线,并且对nginx.conf有任何问题,请告诉我。好吧,这看起来确实有效,但会破坏应用程序。试着用演示内容安装Joomla,你会发现这种行为很奇怪。管理面板工作正常,但大多数文章链接都会抛出404(有些链接在主页内容中没有,我发现这更奇怪)。。。e、 g.此[将在以下情况下加载][你是如何到达那个链接的?@dukeofgaming,你能给我更多关于如何复制你所说的内容的信息吗?你能提供一个例子吗?;在你的另一点上,你的意思是按子域分开应用是最好的做法吗?是的,最好的办法是按子域分开。如果你真的想走推荐路线,你可以在适用的位置有一些
if
语句(例如,在
/
位置(不在
/joomla
位置,例如不创建循环)有
if($http\u referer~ ^/joomla)
)语句,这将
返回302/joomla/$request\u uri;
。如果需要进一步的帮助,请告诉我(查看access_log/error_log以及适用的文件系统布局和nginx.conf也会有帮助,以获得最佳的破解效果)。这没有任何效果,因为您是Joomla开发人员,可以提供Joomla支持,请加入Stack Exchange,看看您是否也可以支持这个专用社区。干杯。