Score:0

การใช้ apache reverse proxy เพื่อส่งคำขอทั้งหมดสำหรับ /blog ไปยังเซิร์ฟเวอร์ wordpress ภายใน

ธง cn

ฉันมีเว็บไซต์ที่เขียนด้วย react และตอนนี้ฉันต้องการเพิ่มส่วนบล็อกลงในไซต์ บล็อกจะใช้ wordpress

แอป react ทำงานในคอนเทนเนอร์นักเทียบท่า และฉันใช้คอนเทนเนอร์นักเทียบท่าเวิร์ดเพรสเพื่อเรียกใช้บล็อกเวิร์ดเพรส

ในการเข้าถึงเว็บไซต์ ฉันใช้คอนเทนเนอร์อื่นที่ใช้ apache และทำหน้าที่เป็น reverse proxy

ข้างใน httpd.conf ไฟล์สำหรับคอนเทนเนอร์ apache ฉันมีส่วนต่อไปนี้:

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

ตัวแปร REACT_SERVER และ BLOG_SERVER มาจากสิ่งแวดล้อม

ปัญหาที่ฉันมีคือเมื่อฉันพยายามเข้าถึงบล็อก apache เปลี่ยนเส้นทางคำขอของฉันไปยังไซต์ wordpress ภายในสำเร็จ แต่เมื่อ wordpress เปลี่ยนเส้นทางของตัวเอง จะใช้โฮสต์เดียวกับ apache แต่เส้นทางไม่ขึ้นต้นด้วย /บล็อกดังนั้นแอปตอบโต้ของฉันจึงพยายามจัดการคำขอ แต่ในที่สุดก็ยอมแพ้และเปลี่ยนเส้นทางของตัวเองไปที่หน้าแรก

นี่คือตัวอย่างการใช้ ขด:

â curl -v http://localhost:3005/blog/
* ลอง 127.0.0.1:3005...
* เชื่อมต่อกับ localhost (127.0.0.1) พอร์ต 3005 (#0)
> รับ /blog/ HTTP/1.1
> โฮสต์: localhost:3005
> User-Agent: curl/7.74.0
> ยอมรับ: */*
>
* ทำเครื่องหมายที่บันเดิลว่าไม่รองรับการใช้งานหลายอย่าง
< พบ HTTP/1.1 302
< วันที่: วันศุกร์ที่ 20 ส.ค. 2564 16:27:32 น. GMT
< เซิร์ฟเวอร์: Apache/2.4.48 (เดเบียน)
< X-ขับเคลื่อนโดย: PHP/7.4.22
< หมดอายุ: วันพุธที่ 11 มกราคม 1984 เวลา 05:00:00 น. GMT
< การควบคุมแคช: ไม่มีแคช ต้องตรวจสอบใหม่ อายุสูงสุด=0
< X-เปลี่ยนเส้นทาง-โดย: WordPress
< ที่ตั้ง: http://localhost:3005/wp-admin/install.php
< ความยาวเนื้อหา: 0
< ประเภทเนื้อหา: text/html; ชุดอักขระ = UTF-8
<
* การเชื่อมต่อ #0 ไปยังโฮสต์ localhost ยังคงอยู่

อย่างที่คุณเห็นหลังจาก X-เปลี่ยนเส้นทาง-โดย ส่วน, the ที่ตั้ง เริ่มต้นด้วย /wp-ผู้ดูแลระบบ แทน /blog/wp-admin.

จาก เอกสาร บน ProxyPassย้อนกลับ:

ตัวอย่างเช่น สมมติว่าโลคัลเซิร์ฟเวอร์มีแอดเดรส http://example.com/; แล้ว

ProxyPass "/mirror/foo/" "http://backend.example.com/"
ProxyPassReverse "/mirror/foo/" "http://backend.example.com/"
ProxyPassReverseCookieDomain "backend.example.com" "public.example.com"
ProxyPassReverseCookiePath "/" "/มิเรอร์/foo/"

จะไม่เพียงทำให้เกิดการร้องขอในท้องถิ่นสำหรับ http://example.com/mirror/foo/bar เพื่อแปลงภายในเป็น ขอมอบฉันทะไปที่ http://backend.example.com/bar (ฟังก์ชั่น ที่ ProxyPass ให้บริการที่นี่) นอกจากนี้ยังดูแลการเปลี่ยนเส้นทางซึ่ง เซิร์ฟเวอร์ backend.example.com ส่งเมื่อเปลี่ยนเส้นทาง http://backend.example.com/bar ถึง http://backend.example.com/quux . Apache httpd ปรับสิ่งนี้เป็น http://example.com/mirror/foo/quux ก่อน ส่งต่อการตอบสนองการเปลี่ยนเส้นทาง HTTP ไปยังไคลเอ็นต์ โปรดทราบว่า ชื่อโฮสต์ที่ใช้สำหรับสร้าง URL ถูกเลือกตาม การตั้งค่าคำสั่ง UseCanonicalName

และดูเหมือนว่านี่คือทั้งหมดที่จำเป็นสำหรับการทำงานนี้ แต่ก็ยังไม่เป็นเช่นนั้น

และหากคุณสงสัยว่า ใช่ ฉันได้ลองแบบธรรมดา (โดยไม่มี ที่ตั้ง คำสั่ง):

ProxyPass "/blog/" "${BLOG_SERVER}/"
ProxyPassReverse "/blog/" "${BLOG_SERVER}/"
ProxyPassReverseCookiePath "/" "/บล็อก"

#ฯลฯ...

และฉันก็ได้รับผลลัพธ์เช่นเดียวกัน

ฉันพลาดอะไรไป

Score:2
ธง in

ปัญหานี้ดูเหมือนว่าจะเป็น Wordpress มากกว่าการกำหนดค่าผิด คุณต้องบอก wordpress ว่ามันอยู่ในไดเรกทอรีย่อย เพราะตอนนี้ไฟล์ wordpress .htaccess เริ่มต้นกำลังเปลี่ยนเส้นทางคุณไปที่ http://localhost:3005/wp-admin/install.php เนื่องจากไม่ทราบว่าอยู่ในไดเรกทอรี เรียกว่า บล็อก.

ตัวเลือกที่ 1. วิธีหนึ่งในการแก้ปัญหานี้คือบอก wordpress ว่ามี url ฐานใหม่ในไฟล์ wp-config.php

กำหนด ('WP_HOME','http://example.com/blog');
กำหนด ('WP_SITEURL','http://example.com/blog');

ตัวเลือก 2 อีกวิธีในการพยายามจัดการกับสิ่งนี้คือแก้ไขไฟล์ htaccess ของ wordpress

ไฟล์ htaccess ของคุณใน wordpress ควรมีลักษณะดังนี้

<IfModule mod_rewrite.c>
RewriteEngine เปิดอยู่
RewriteBase /blog/
RewriteRule ^index\.php$ - [L]
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
กฎการเขียนซ้ำ /blog/index.php [L]

นี่จะเป็น htaccess ที่มีอยู่ในคอนเทนเนอร์ตัวเทียบท่าของ wordpress

smac89 avatar
cn flag
ขอบคุณสำหรับคำตอบ. แน่นอนว่าการใช้ `WP_HOME` และ `WP_SITEURL` เป็นวิธีหนึ่งในการแก้ปัญหานี้ แต่ฉันต้องการดูว่าสามารถทำได้โดยใช้เพียง apache, mod_proxy ซึ่งเป็นสาเหตุที่ [answer](https://serverfault.com) ของฉัน /a/1075300/257206) อยู่ด้วย
Score:0
ธง cn

โอเค ฉันคิดว่าฉันเข้าใจปัญหาแล้ว

Wordpress ใช้ตัวแปรสองตัวเพื่อกำหนด:

  1. URL ใดที่นำไปสู่ตำแหน่งของไซต์เวิร์ดเพรสของคุณ (WP_HOME)
  2. URL ใดที่ใช้ในการโหลดทรัพยากรสำหรับเว็บไซต์ wordpress ของคุณ (WP_SITEURL)

สิ่งแรกที่ฉันต้องทำสำหรับคอนเทนเนอร์เวิร์ดเพรสคือต้องแน่ใจว่า URL เหล่านี้ตรงกับ URL ของคอนเทนเนอร์ภายใน เช่น $BLOG_SERVER. เนื่องจากฉันใช้ docker-compose จึงเป็นเรื่องง่ายที่จะใส่ URL นี้โดยใช้ตัวแปรสภาพแวดล้อมผ่าน WORDPRESS_CONFIG_EXTRA การโต้แย้ง.

เวิร์ดเพรสบล็อก:
  ภาพ: wordpress:5
  ขึ้นอยู่กับ:
    - บล็อกฐานข้อมูล
  สิ่งแวดล้อม:
    WORDPRESS_DB_HOST: บล็อกฐานข้อมูล
    WORDPRESS_DB_NAME: บล็อก
    WORDPRESS_DB_USER: เวิร์ดเพรส
    WORDPRESS_DB_PASSWORD: เวิร์ดเพรส
    WORDPRESS_CONFIG_EXTRA: |
      กำหนด ('WP_HOME', 'http://wordpress-blog');
      กำหนด ('WP_SITEURL', 'http://wordpress-blog');
  ปริมาณ:
    - เวิร์ดเพรส:/var/www/html

เสร็จแล้ว ตอนนี้เราสามารถมุ่งเน้นไปที่พร็อกซี

ก่อนที่ฉันจะใช้เส้นทางของ reverse proxy แบบเต็ม ฉันอยู่ภายใต้การสันนิษฐานว่า proxy จะเข้าควบคุมทุกคำขอสำหรับ /บล็อก/ และส่งคืนหน้าจากไซต์พร็อกซีซึ่งจะดูราวกับว่าพวกเขาให้บริการโดยตรงจากเวิร์ดเพรส สิ่งหนึ่งที่ฉันไม่ได้คำนึงถึงก็คือสมมติฐานนี้ก็สันนิษฐานเช่นกัน หน้าเรนเดอร์ฝั่งเซิร์ฟเวอร์.

เริ่มต้นด้วยสิ่งใหม่ โฮสต์เสมือน คอนฟิกูเรชัน ตอนนี้หน้าตาจะเป็นดังนี้:

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

สิ่งต่อไปที่ฉันต้องทำเพื่อให้พร็อกซีนี้เริ่มทำงานเหมือนพร็อกซีคือเพิ่มบรรทัดนี้:

ปิด ProxyPreserveHost

สิ่งนี้ทำให้มั่นใจได้ว่าการตอบกลับ/คำขอทั้งหมดที่เราได้รับจาก wordpress จะไม่ดูเหมือนว่ามาจากเรา (พร็อกซี) เหตุผลนี้จะชัดเจนในไม่ช้าเมื่อเราเริ่มจัดการกับ proxying html


ต่อไป พร็อกซีพาส คำสั่งถูกย้ายออกจาก ที่ตั้ง ภาชนะและตรงเข้า โฮสต์เสมือน.

ProxyPass "/blog/" "${BLOG_SERVER}/"
ProxyPass "/" "${REACT_SERVER}/"

สาเหตุที่เป็นเช่นนี้เพราะว่า ที่ตั้ง การบล็อกล่าช้ามากในการจับคู่คำขอ และบางครั้งการ / เส้นทางชัยชนะเหนือ /บล็อก/ เส้นทาง. ฉันต้องการให้มันน่าเชื่อถือกว่านี้ฉันจึงตัดสินใจเลือกผู้รับมอบฉันทะด้วยตัวเอง (ฉันเห็นตัวอย่าง ที่นี่) จากนั้นแก้ไขพาธภายในไฟล์ ที่ตั้ง คอนเทนเนอร์.


ณ จุดนี้พร็อกซีย้อนกลับอยู่ในขณะนี้ ทำงาน! อย่างไรก็ตาม html ในหน้านั้นมีลิงค์ที่ชี้ไปยัง url ภายในของไซต์ wordpress ที่นี่เป็นที่ที่ mod_proxy_html เข้ามาสามารถใช้เขียนลิงค์ทั้งหมดใน html ใหม่เพื่อชี้ไปที่ reverse proxy ทุกที่ที่พบลิงก์ที่ชี้ไปยังไซต์บล็อกภายใน ลิงก์นั้นจะถูกแทนที่ด้วยลิงก์ที่ใช้พร็อกซีย้อนกลับ

ProxyHTMLEnable เปิด
ProxyHTMLขยายบน
ProxyHTMLURLMap "${BLOG_SERVER}/"
SetOutputFilter INFLATE;proxy-html;DEFLATE

บรรทัดสุดท้ายอาจทำให้เกิดปัญหาคอขวด เนื่องจากบรรทัดสุดท้ายจะขยายเพย์โหลดจากเว็บไซต์บล็อก เขียน URL ใหม่ทั้งหมดเพื่อชี้ไปยังพร็อกซีย้อนกลับ จากนั้นจึงบีบอัดอีกครั้ง หากคุณไม่ต้องการสิ่งนี้ อีกวิธีที่จะทำให้สำเร็จคือใช้:

RequestHeader ยกเลิกการตั้งค่าการยอมรับการเข้ารหัส

แม้จะมีทั้งหมดนี้แล้ว โซลูชันก็ยังไม่สมบูรณ์แบบ เนื่องจากไฟล์จาวาสคริปต์ใดๆ ที่โหลดบนหน้าเว็บ ซึ่งส่งคำขอไปยังไซต์ภายในจะไม่ส่งคำขอไปยังพร็อกซี

ทางออกหนึ่งสำหรับสิ่งนี้คือการใช้วิธีแก้ปัญหาแรกที่เสนอโดย คำตอบปัจจุบัน ในคำถามนี้และการเปลี่ยนแปลง WP_SITEURL เพื่อชี้ไปที่พร็อกซีย้อนกลับโดยตรง

อีกวิธีหนึ่งคือการใช้ พนักงานบริการ ถึง สกัดกั้นคำขอของเครือข่าย. ฉันชอบโซลูชันนี้เนื่องจากไม่ได้เชื่อมโยงไซต์บล็อกเข้ากับพร็อกซีย้อนกลับอย่างแน่นหนา ฉันสามารถจินตนาการได้ว่ามันจะไม่เป็นการดึงข้อมูลมากเกินไป (เฮ้) ความคิดที่จะใส่พนักงานบริการลงในหน้า html ใด ๆ ที่ร้องขอจากพร็อกซี และให้พนักงานบริการนั้นสกัดกั้นคำขอทั้งหมดที่ตรงกับ URL ของเว็บไซต์บล็อกภายใน และแทนที่ ด้วย URL พร็อกซีย้อนกลับ

ฉันไปกับสิ่งเหล่านี้ หลังจากการไตร่ตรองอย่างถี่ถ้วน ฉันคิดว่าการโฮสต์ wordpress ในโดเมนย่อยน่าจะเหมาะกับความต้องการของฉันมากกว่า บางอย่างเช่น blog.example.com เป็นสิ่งที่ฉันอาจทำ แต่นั่นอาจใช้ได้ผลในวันอื่น


สรุปได้ว่า reverse proxy ใช้งานกับ apache ได้ยาก ฉันไม่รู้ว่าหญ้าจะเขียวกว่าฝั่ง nginx หรือไม่ แต่สักวันหนึ่งเราจะลองดู วิธีแก้ปัญหาที่ฉันใช้คือเนื้อหาฝั่งเซิร์ฟเวอร์เท่านั้น ซึ่งจะพิสูจน์แล้วว่าเป็นตัวเลือกที่สมบูรณ์แบบสำหรับการใช้พร็อกซี แต่อนิจจา เนื้อหาที่โหลดแบบไดนามิกจะต้องใช้งานมากขึ้น

แหล่งที่มา

เปิดใช้งานโมดูล Apache สำหรับ html proxying

LoadModule deflate_module โมดูล/mod_deflate.so
LoadModule xml2enc_module โมดูล/mod_xml2enc.so
LoadModule proxy_html_module modules/mod_proxy_html.so

โพสต์คำตอบ

คนส่วนใหญ่ไม่เข้าใจว่าการถามคำถามมากมายจะปลดล็อกการเรียนรู้และปรับปรุงความสัมพันธ์ระหว่างบุคคล ตัวอย่างเช่น ในการศึกษาของ Alison แม้ว่าผู้คนจะจำได้อย่างแม่นยำว่ามีคำถามกี่ข้อที่ถูกถามในการสนทนา แต่พวกเขาไม่เข้าใจความเชื่อมโยงระหว่างคำถามและความชอบ จากการศึกษาทั้ง 4 เรื่องที่ผู้เข้าร่วมมีส่วนร่วมในการสนทนาด้วยตนเองหรืออ่านบันทึกการสนทนาของผู้อื่น ผู้คนมักไม่ตระหนักว่าการถามคำถามจะมีอิทธิพลหรือมีอิทธิพลต่อระดับมิตรภาพระหว่างผู้สนทนา