Puncte:0

Folosind apache reverse proxy pentru a trimite toate solicitările pentru /blog către serverul wordpress intern

drapel cn

Am un site scris in react, iar acum am vrut sa adaug o sectiune de blog pe site. Blogul se va baza pe wordpress.

Aplicația react rulează într-un container docker, iar eu folosesc containerul docker wordpress pentru a rula blogul wordpress.

Pentru a accesa site-ul, folosesc un alt container care rulează apache și acționează ca un proxy invers.

În interiorul httpd.conf fișier pentru containerul apache, am următoarea secțiune:

<VirtualHost *:80>
    <Location "/">
        ProxyPreserveHost On
        ProxyPass "${REACT_SERVER}/"
        ProxyPassReverse "${REACT_SERVER}/"
    </Location>

    <Location /blog>
        ProxyPreserveHost On
        ProxyPass "${BLOG_SERVER}/"
        ProxyPassReverse "${BLOG_SERVER}/"
        ProxyPassReverseCookiePath  "/"  "/blog"
    </Location>

    # more config for handling websockets
</VirtualHost>

Variabilele REACT_SERVER și BLOG_SERVER provin din mediu.

Problema pe care o am este că atunci când încerc să accesez blogul, apache redirecționează cu succes solicitarea mea către site-ul wordpress intern, dar când wordpress își face propria redirecționare, folosește aceeași gazdă ca apache, dar calea nu începe cu /blog, așa că aplicația mea react încearcă să gestioneze cererea, dar în cele din urmă renunță și își face propria redirecționare către pagina de pornire.

Iată un exemplu de utilizare răsuci:

â curl -v http://localhost:3005/blog/
* Se încearcă 127.0.0.1:3005...
* Conectat la portul localhost (127.0.0.1) 3005 (#0)
> GET /blog/ HTTP/1.1
> Gazdă: localhost:3005
> User-Agent: curl/7.74.0
> Accept: */*
>
* Marcați pachetul ca nu acceptă mai multe utilizări
< HTTP/1.1 302 Găsit
< Data: vineri, 20 august 2021 16:27:32 GMT
< Server: Apache/2.4.48 (Debian)
< X-Powered-By: PHP/7.4.22
< Expiră: miercuri, 11 ianuarie 1984 05:00:00 GMT
< Cache-Control: fără cache, revalidare obligatorie, vârsta maximă=0
< X-Redirect-By: WordPress
< Locație: http://localhost:3005/wp-admin/install.php
< Lungimea conținutului: 0
< Content-Type: text/html; set de caractere=UTF-8
<
* Conexiunea #0 la gazda localhost a rămas intactă

După cum puteți vedea, după X-Redirecționat-De secțiunea, the Locație incepe cu /wp-admin în loc de /blog/wp-admin.

De la docs pe ProxyPassReverse:

De exemplu, să presupunem că serverul local are o adresă http://example.com/; atunci

ProxyPass „/mirror/foo/” „http://backend.example.com/”
ProxyPassReverse "/mirror/foo/" "http://backend.example.com/"
ProxyPassReverseCookieDomain „backend.example.com” „public.example.com”
ProxyPassReverseCookiePath "/" "/mirror/foo/"

nu va provoca doar o cerere locală pentru http://example.com/mirror/foo/bar a fi convertit intern într-o cerere de proxy către http://backend.example.com/bar (funcționalitatea pe care ProxyPass îl oferă aici). Se ocupă și de redirecționări care serverul backend.example.com îl trimite la redirecționare http://backend.example.com/bar la http://backend.example.com/quux . Apache httpd ajustează acest lucru la http://example.com/mirror/foo/quux inainte de redirecționarea răspunsului de redirecționare HTTP către client. Rețineți că numele gazdă folosit pentru construirea URL-ului este ales în raport cu setarea directivei UseCanonicalName.

și se pare că asta este tot ceea ce este necesar pentru ca acest lucru să funcționeze, dar tot nu funcționează.

Și dacă te întrebi, da Am încercat câmpia (fără Locație directivă):

ProxyPass „/blog/” „${BLOG_SERVER}/”
ProxyPassReverse „/blog/” „${BLOG_SERVER}/”
ProxyPassReverseCookiePath „/” „/blog”

# etc...

Și obțin aceleași rezultate.

Ce îmi lipsește?

Puncte:2
drapel in

Această problemă pare să fie mai mult un lucru Wordpress decât o configurare greșită. Trebuie să spuneți wordpress că locuiește într-un subdirector, deoarece în acest moment fișierul implicit wordpress .htaccess vă redirecționează către http://localhost:3005/wp-admin/install.php , deoarece nu știe că se află într-un director numit blog.

Opțiunea 1. O modalitate de a încerca și de a rezolva acest lucru este să spuneți wordpress că are o nouă adresă URL de bază în fișierul wp-config.php

define('WP_HOME','http://example.com/blog');
define('WP_SITEURL','http://example.com/blog');

Opțiunea 2. Un alt mod de a încerca să gestionați acest lucru este să editați fișierul htaccess al wordpress

Fișierul dvs. htaccess din wordpress ar trebui să arate cam așa

<IfModule mod_rewrite.c>
RewriteEngine Pornit
RewriteBase /blog/
RewriteRule ^index\.php$ - [L]
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule . /blog/index.php [L]

Acesta ar fi htaccess-ul care există în interiorul containerului docker wordpress

smac89 avatar
drapel cn
Multumesc pentru raspunsul tau. Într-adevăr, folosirea `WP_HOME` și `WP_SITEURL` ar fi fost o modalitate de a rezolva acest lucru, dar am vrut să văd dacă se poate face și folosind doar apache, mod_proxy, motiv pentru care [răspunsul](https://serverfault.com) /a/1075300/257206) există și.
Puncte:0
drapel cn

Ok, cred ca mi-am dat seama de problema.

Wordpress folosește două variabile pentru a determina:

  1. Care adresă URL duce la locația site-ului dvs. wordpress (WP_HOME)
  2. Ce adresă URL este folosită pentru a încărca resurse pentru site-ul dvs. wordpress (WP_SITEURL)

Primul lucru pe care a trebuit să-l fac pentru containerul wordpress a fost să mă asigur că aceste adrese URL se potrivesc cu adresa URL a containerului intern, adică. $BLOG_SERVER. Deoarece folosesc docker-compose, a fost ușor să injectez această adresă URL folosind variabile de mediu prin intermediul WORDPRESS_CONFIG_EXTRA argument.

wordpress-blog:
  imagine: wordpress:5
  depinde de:
    - blog-db
  mediu inconjurator:
    WORDPRESS_DB_HOST: blog-db
    WORDPRESS_DB_NAME: blog
    WORDPRESS_DB_USER: wordpress
    WORDPRESS_DB_PASSWORD: wordpress
    WORDPRESS_CONFIG_EXTRA: |
      define('WP_HOME', 'http://wordpress-blog');
      define('WP_SITEURL', 'http://wordpress-blog');
  volume:
    - wordpress:/var/www/html

Acum că s-a terminat, ne putem concentra pe proxy.

Înainte să merg pe calea proxy-ului invers complet, am presupus că proxy-ul va prelua cumva fiecare cerere de /blog/ și returnează pagini de pe site-ul proxy care vor arăta ca și cum ar fi fost difuzate direct din wordpress. Un lucru pe care nu l-am luat în considerare a fost că și această presupunere a presupus pagini randate pe partea serverului.

Începând cu noul VirtualHost configurație, așa arată acum:

<VirtualHost *:80>
    ProxyPass "/blog/" "${BLOG_SERVER}/"
    ProxyPass "/" "${REACT_SERVER}/"

    <Location "/">
        ProxyPreserveHost On
        ProxyErrorOverride On
        ProxyPassReverse "${DEV_SERVER}/"
    </Location>

    <Location "/blog/">
        ProxyPreserveHost Off
        ProxyPassReverse "${BLOG_SERVER}/"
        ProxyPassReverseCookiePath  "/"  "/blog/"
        ProxyErrorOverride On

        ProxyHTMLEnable On
        ProxyHTMLExtended On
        ProxyHTMLURLMap "${BLOG_SERVER}/"
        SetOutputFilter INFLATE;proxy-html;DEFLATE
        # ProxyPassReverseCookieDomain "%{HTTP_HOST:${BLOG_SERVER}}" %{HTTP_HOST}
    </Location>
</VirtualHost>

Următorul lucru pe care a trebuit să-l fac pentru ca acest proxy să înceapă să se comporte ca un proxy a fost să adaug această linie:

ProxyPreserveHost dezactivat

Acest lucru asigură că toate răspunsurile/solicitările pe care le primim de la wordpress nu arată ca și cum ar fi venit de la noi (proxy). Motivul pentru aceasta va fi în curând evident când vom începe să ne ocupăm de proxy html.


În continuare ProxyPass directivele au fost mutate din Locație container și direct în VirtualHost.

ProxyPass „/blog/” „${BLOG_SERVER}/”
ProxyPass „/” „${REACT_SERVER}/”

Motivul pentru aceasta este pentru că Locație blocurile întârziau foarte mult în potrivirea cererilor, iar uneori / calea învinge asupra /blog/ cale. Aveam nevoie ca acesta să fie mai de încredere, așa că am decis să merg cu specificarea proxy-urilor pe cont propriu (am văzut un exemplu Aici), apoi modificând căile din interiorul Locație recipient.


În acest moment, proxy-ul invers este acum lucru! Cu toate acestea, html-ul din pagini avea legături care indicau adresa URL internă a site-ului wordpress. Aici este locul mod_proxy_html intră. Poate fi folosit pentru a rescrie toate linkurile în html pentru a indica proxy-ul invers. Oriunde găsește un link care indică site-ul blogului intern, linkul este înlocuit cu unul care folosește proxy invers.

ProxyHTML Enable Activat
ProxyHTMLExtended Activat
ProxyHTMLURLHarta „${BLOG_SERVER}/”
SetOutputFilter INFLATE;proxy-html;DEFLATE

Ultima linie ar putea introduce un blocaj deoarece, în esență, decomprimă sarcina utilă de pe site-ul blogului, rescrie toate adresele URL pentru a indica proxy-ul invers, apoi le comprimă din nou. Dacă nu doriți acest lucru, o altă modalitate de a realiza acest lucru este să utilizați:

RequestHeader dezactivat Accept-Encoding

Chiar și cu toate acestea la locul lor, soluția încă nu era perfectă, deoarece orice fișier javascript încărcat pe pagină, care face o solicitare către site-ul intern, nu va avea solicitările lor direcționate către proxy.

O soluție la acest lucru ar fi să mergeți cu prima soluție propusă de răspunsul curent pe această întrebare și în schimbare WP_SITEURL pentru a indica direct proxy-ul invers.

O altă soluție este folosirea unui Lucrator de service la interceptarea cererilor de rețea. Îmi place această soluție pentru că nu cuplează strâns site-ul blogului cu proxy-ul invers. Mi-aș putea imagina că nu ar fi o idee prea exagerată (heh) să injectăm lucrătorul de serviciu în orice pagini html solicitate de la proxy și să îl punem pe acel lucrător de serviciu să intercepteze toate solicitările care se potrivesc cu adresa URL a site-ului blogului intern și să înlocuiască ei cu URL-ul proxy invers.

Nu am mers cu niciuna dintre acestea. După multă deliberare, cred că găzduirea wordpress într-un subdomeniu ar fi mai bună pentru nevoile mele. Aș putea alege ceva de genul blog.example.com, dar asta ar fi de lucru pentru o altă zi.


În concluzie, proxy-urile inverse sunt dificil de implementat corect cu apache. Nu știu dacă iarba este mai verde pe partea nginx, dar poate cândva o vom verifica. Soluția pe care o căutam presupunea conținut exclusiv pe server, care s-ar fi dovedit a fi un candidat perfect pentru a fi proxy, dar, din păcate, conținutul încărcat dinamic va necesita mai multă muncă.

Surse

Modulele Apache activate pentru proxy html

LoadModule deflate_module modules/mod_deflate.so
LoadModule xml2enc_module modules/mod_xml2enc.so
LoadModule proxy_html_module modules/mod_proxy_html.so

Postează un răspuns

Majoritatea oamenilor nu înțeleg că a pune multe întrebări deblochează învățarea și îmbunătățește legătura interpersonală. În studiile lui Alison, de exemplu, deși oamenii își puteau aminti cu exactitate câte întrebări au fost puse în conversațiile lor, ei nu au intuit legătura dintre întrebări și apreciere. În patru studii, în care participanții au fost implicați în conversații ei înșiși sau au citit transcrieri ale conversațiilor altora, oamenii au avut tendința să nu realizeze că întrebarea ar influența – sau ar fi influențat – nivelul de prietenie dintre conversatori.