Heim  >  Fragen und Antworten  >  Hauptteil

Netter hinter dem Reverse-Proxy-Alias ​​auf Nginx

<p>Ich habe eine Nette-Anwendung, die auf einem Apache2/Debian 11-Server läuft und sie funktioniert einwandfrei. Allerdings müssen wir einen Alias ​​verwenden, um es hinter dem Nginx-Proxy zu verbergen. </p> <p>Angenommen, wir haben eine perfekte Apache2-Umgebung, die unter http://127.0.0.1:89/ läuft, und wir möchten über Nginx darauf zugreifen, das als Reverse-Proxy unter https://example.com/applications/< eingerichtet ist ;/p> <p>nginx-Einstellungen lauten wie folgt:</p> <pre class="brush:php;toolbar:false;">location /app/ { Proxy_Pass http://127.0.0.1:89; Proxy_set_header Host $host; Proxy_set_header X-Forwarded-Host $host; Proxy_set_header X-Forwarded-Proto "https"; Proxy_set_header X-Forwarded-Port „443“; Proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; }</pre> <p>Während die Apache2-Konfiguration unverändert bleibt, bevor der Proxy versucht: </p> <pre class="brush:php;toolbar:false;"><VirtualHost *:89> ServerAdmin webmaster@localhost DocumentRoot /var/www/app/www/ <Verzeichnis /var/www/app/www/> Optionsindizes FollowSymLinks AllowOverride All Fordern Sie alles gewährt </Verzeichnis> </VirtualHost></pre> <p>Das Problem besteht darin, dass die Nette-Anwendung immer noch denkt, dass sie auf einem Pfad ohne den URI-Teil „/app“ ausgeführt wird, sodass alle durch Weiterleitungen und Linkaufrufe generierten Links (einschließlich der Vorlagenvariablen $basePath) ungültig sind. < /p> <p>Ich habe auch die Proxy-Informationen an die Nette-Konfiguration angehängt, und da die Nginx-Instanz auf demselben Server läuft, sieht es so aus: </p> <pre class="brush:php;toolbar:false;">http: Proxy: 127.0.0.1</pre> <p>Ich habe versucht, die Nginx-Konfiguration so einzustellen, dass der /admin-Pfad im weitergeleiteten URI weitergeleitet wird: </p> <pre class="brush:php;toolbar:false;">proxy_pass http://127.0.0.1:89/admin;</pre> <p>Und habe auch versucht, mit dem Nette-Router herumzuspielen, um den „admin/“-Teil herauszufiltern (ohne nach dem AdminPresenter zu suchen, der offensichtlich fehlt): </p> <pre class="brush:php;toolbar:false;">$router->addRoute('[admin/]<presenter>/<action>[/<id>]', 'Homepage: default');</pre> <p>Die Nette-Anwendung generiert diesen Fehler, wenn sie versucht, auf die Seite zuzugreifen: </p> <pre class="brush:php;toolbar:false;">TypeError: unpack() erwartet, dass Parameter 2 ein String, Bool ist, der in /var/www/app/vendor/nette/http/src/Http/Helpers angegeben ist .php:49 @ http://example.com/app/</pre> <p>Kann mir jemand den richtigen Weg weisen? </p>
P粉953231781P粉953231781432 Tage vor581

Antworte allen(1)Ich werde antworten

  • P粉035600555

    P粉0356005552023-09-04 17:09:20

    好吧,回答我自己的问题,以防有人遇到同样的问题。我觉得我的解决方案有点黑客,所以请随意发布非黑客答案。

    首先,我修改了 nginx 配置:

    location /app/ {
        rewrite /app/(.*) /app/$1 break;
        proxy_pass http://127.0.0.1:89/;
        proxy_set_header Host $host;
        proxy_set_header X-Forwarded-Host $host;
        proxy_set_header X-Forwarded-Proto "https";
        proxy_set_header X-Forwarded-Port "443";
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
    }

    然后我修改了 Nette 配置以覆盖所有代理(可能实际上并不需要):

    http:
        proxy: 0.0.0.0/0

    我还在路由器代码中添加了“app”路由(不是作为可选前缀,而是作为常规路由):

    $router = new RouteList;
    $router->addRoute('app/<presenter>/<action>[/<id>]', 'Homepage:default');
    $router->addRoute('<presenter>/<action>[/<id>]', 'Homepage:default');
    return $router;

    还修改了BasePresenter代码启动方法:

    $this->template->basePath = '/app'.$this->template->basePath;

    最后,我修改了.htaccess文件,将所有静态资源的URL重写为不包含“app”部分的路径:

    # Default Nette htaccess contents
    RewriteEngine On
    RewriteRule /\.|^\. - [F]
    
    RewriteCond %{REQUEST_FILENAME} !-f
    RewriteCond %{REQUEST_FILENAME} !-d
    RewriteRule !\.(pdf|js|ico|gif|jpg|png|css|rar|zip|tar\.gz)$ index.php [L]
    
    # Added this line under the default Nette htaccess file
    RewriteRule ^app(/.*|$) $1 [NC,L]

    Apache 虚拟主机保持不变。

    这样,nginx 将完整的请求 URL(包括“app”)传递给 Apache,Apache 使用“app”前缀调用 Nette 路由器。路由现在工作正常,因为“应用程序”是 URL 的一部分,甚至可以被 Nette 感知(因为它实际上完全存在于请求标头中)。这会导致 $basePath 和 links/redirect 工作。

    但是,静态资源不是通过 Nette 路由器提供的,因此 app/ 前缀会导致 Apache 找不到该文件并报告 404。这就是添加重写规则的原因从静态资源的 URL 中删除 app/ 前缀。

    它很hacky,但它适用于代理和非代理访问。

    Antwort
    0
  • StornierenAntwort