Maison  >  Questions et réponses  >  le corps du texte

Nette derrière l'alias de proxy inverse sur nginx

<p>J'ai une application Nette exécutée sur un serveur Apache2/Debian 11 et elle fonctionne bien. Cependant, nous devons utiliser un alias pour le cacher derrière le proxy nginx. </p> <p>Supposons que nous ayons un environnement Apache2 parfait fonctionnant sur http://127.0.0.1:89/ et que nous souhaitions y accéder via nginx configuré en tant que proxy inverse sur https://example.com /applications/< ;/p> <p>les paramètres nginx sont les suivants :</p> <pre class="brush:php;toolbar:false;">emplacement /app/ { proxy_pass http://127.0.0.1:89 ; proxy_set_header Hôte $host ; proxy_set_header X-Forwarded-Host $host; proxy_set_header X-Forwarded-Proto "https" ; proxy_set_header Port X-Forwarded "443" ; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; }</pré> <p>Alors que la configuration d'Apache2 reste inchangée avant les tentatives du proxy : </p> <pre class="brush:php;toolbar:false;"><VirtualHost *:89> Administrateur du serveur webmaster@localhost DocumentRoot /var/www/app/www/ <Répertoire /var/www/app/www/> Index des options FollowSymLinks Autoriser tout remplacer Exiger que tout soit accordé </Répertoire> </VirtualHost></pre> <p>Le problème est que l'application Nette pense toujours qu'elle s'exécute sur un chemin sans la partie URI "/app", donc tous les liens générés via des redirections et des appels de lien (y compris la variable de modèle $basePath) ne sont pas valides. ≪ /p> <p>J'ai également ajouté les informations de proxy à la configuration de Nette, et comme l'instance nginx s'exécute sur le même serveur, elle ressemble à ceci : </p> <pre class="brush:php;toolbar:false;">http : proxy : 127.0.0.1</pre> <p>J'ai essayé de configurer la configuration nginx pour transférer le chemin /admin dans l'URI transféré : </p> <pre class="brush:php;toolbar:false;">proxy_pass http://127.0.0.1:89/admin;</pre> <p>Et j'ai également essayé de jouer avec le routeur Nette pour filtrer la partie "admin/" (sans chercher le AdminPresenter, qui est évidemment manquant) : </p> <pre class="brush:php;toolbar:false;">$router->addRoute('[admin/]<presenter>/<action>[/<id>]', 'Page d'accueil : par défaut');</pre> <p>L'application Nette génère cette erreur lors de la tentative d'accès à la page : </p> <pre class="brush:php;toolbar:false;">TypeError : unpack() s'attend à ce que le paramètre 2 soit une chaîne, bool donné dans /var/www/app/vendor/nette/http/src/Http/Helpers .php:49 @ http://example.com/app/</pre> <p>Quelqu’un peut-il m’indiquer la bonne direction ? </p>
P粉953231781P粉953231781381 Il y a quelques jours540

répondre à tous(1)je répondrai

  • P粉035600555

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

    D'accord, je réponds à ma propre question au cas où quelqu'un aurait le même problème. J'ai l'impression que ma solution est un peu un hack, alors n'hésitez pas à publier des réponses non hackées.

    Tout d'abord, j'ai modifié la configuration de nginx :

    location /app/ {
        rewrite /app/(.*) /app/ 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;
    }

    Ensuite, j'ai modifié la configuration de Nette pour couvrir tous les proxys (probablement pas réellement nécessaires) :

    http:
        proxy: 0.0.0.0/0

    J'ai également ajouté la route "app" dans le code du routeur (non pas comme préfixe facultatif, mais comme route régulière) :

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

    A également modifié la méthode de démarrage du code BasePresenter :

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

    Enfin, j'ai modifié le fichier .htaccess pour réécrire les URL de toutes les ressources statiques vers des chemins qui ne contiennent pas la partie "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(/.*|$)  [NC,L]

    L'hôte virtuel Apache reste inchangé.

    De cette façon, nginx transmet l'URL complète de la requête (y compris "app") à Apache, et Apache appelle le routeur Nette en utilisant le préfixe "app". Le routage fonctionne désormais correctement car "application" fait partie de l'URL et en est même consciente par Nette (puisqu'elle est en fait entièrement présente dans l'en-tête de la requête). Cela fait fonctionner $basePath et les liens/redirections.

    Cependant, les ressources statiques ne sont pas servies via le routeur Nette, d'où le préfixe app/ 前缀会导致 Apache 找不到该文件并报告 404。这就是添加重写规则的原因从静态资源的 URL 中删除 app/.

    C'est hacky, mais cela fonctionne à la fois pour l'accès proxy et non proxy.

    répondre
    0
  • Annulerrépondre