Điểm:0

Sử dụng proxy ngược apache để gửi tất cả các yêu cầu cho/blog đến máy chủ wordpress nội bộ

lá cờ cn

Tôi có một trang web được viết bằng phản ứng và bây giờ tôi muốn thêm một phần blog vào trang web. Blog sẽ được dựa trên wordpress.

Ứng dụng phản ứng chạy trong bộ chứa docker và tôi sử dụng bộ chứa docker wordpress để chạy blog wordpress.

Để truy cập trang web, tôi sử dụng một bộ chứa khác chạy apache và hoạt động như một proxy ngược.

Bên trong httpd.conf tệp cho bộ chứa apache, tôi có phần sau:

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

các biến REACT_SERVERBLOG_SERVER đến từ môi trường.

Vấn đề tôi gặp phải là khi tôi cố gắng truy cập blog, apache đã chuyển hướng thành công yêu cầu của tôi đến trang web wordpress nội bộ, nhưng khi wordpress thực hiện chuyển hướng của chính nó, nó sử dụng cùng một máy chủ như apache, nhưng đường dẫn không bắt đầu bằng /Blog, vì vậy ứng dụng phản ứng của tôi cố gắng xử lý yêu cầu nhưng cuối cùng lại từ bỏ và tự chuyển hướng đến trang chủ.

Đây là một ví dụ sử dụng Xoăn:

â curl -v http://localhost:3005/blog/
* Đang thử 127.0.0.1:3005...
* Đã kết nối với localhost (127.0.0.1) cổng 3005 (#0)
> NHẬN /blog/ HTTP/1.1
> Máy chủ: localhost:3005
> Tác nhân người dùng: curl/7.74.0
> Chấp nhận: */*
>
* Đánh dấu gói là không hỗ trợ đa dụng
< HTTP/1.1 302 Đã tìm thấy
< Ngày: Thứ Sáu, ngày 20 tháng 8 năm 2021 16:27:32 GMT
< Máy chủ: Apache/2.4.48 (Debian)
< X-Powered-By: PHP/7.4.22
< Hết hạn: Thứ tư, ngày 11 tháng 1 năm 1984 05:00:00 GMT
< Kiểm soát bộ đệm: không có bộ đệm, phải xác thực lại, max-age=0
< X-Redirect-By: WordPress
< Vị trí: http://localhost:3005/wp-admin/install.php
< Độ dài nội dung: 0
< Loại nội dung: văn bản/html; bộ ký tự = UTF-8
<
* Kết nối #0 đến host localhost còn nguyên

Như bạn có thể thấy, sau khi X-Redirected-By phần, các Địa điểm bắt đầu với /wp-admin thay vì /blog/wp-admin.

Từ tài liệu trên ProxyPassĐảo ngược:

Ví dụ: giả sử máy chủ cục bộ có địa chỉ http://example.com/; sau đó

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

sẽ không chỉ gây ra một yêu cầu cục bộ cho http://example.com/mirror/foo/bar được chuyển đổi nội bộ thành một yêu cầu proxy đến http://backend.example.com/bar (chức năng mà ProxyPass cung cấp ở đây). Nó cũng quan tâm đến các chuyển hướng mà máy chủ backend.example.com gửi khi chuyển hướng http://backend.example.com/bar đến http://backend.example.com/quux . Apache httpd điều chỉnh điều này thành http://example.com/mirror/foo/quux trước chuyển tiếp phản hồi chuyển hướng HTTP tới máy khách. Lưu ý rằng tên máy chủ được sử dụng để xây dựng URL được chọn đối với cài đặt của chỉ thị UseCanonicalName.

và có vẻ như đây là tất cả những gì cần thiết để nó hoạt động, nhưng nó vẫn không hoạt động.

Và nếu bạn đang tự hỏi, Vâng Tôi đã thử đồng bằng (không có Địa điểm chỉ thị):

ProxyPass "/blog/" "${BLOG_SERVER}/"
ProxyPassReverse "/blog/" "${BLOG_SERVER}/"
ProxyPassReverseCookiePath "/" "/blog"

# vân vân...

Và tôi cũng nhận được kết quả tương tự.

Tôi đang thiếu gì?

Điểm:2
lá cờ in

Vấn đề này có vẻ giống như một vấn đề về Wordpress hơn là do cấu hình sai. Bạn cần nói với wordpress rằng nó đang nằm trong một thư mục con, bởi vì ngay bây giờ, tệp .htaccess mặc định của wordpress đang chuyển hướng bạn đến http://localhost:3005/wp-admin/install.php , vì nó không biết nó nằm trong một thư mục gọi điện Blog.

Lựa chọn 1. Một cách để thử và giải quyết vấn đề này là nói với wordpress rằng nó có một url cơ sở mới trong tệp wp-config.php

xác định ('WP_HOME','http://example.com/blog');
xác định ('WP_SITEURL','http://example.com/blog');

Lựa chọn 2. Một cách khác để thử và xử lý việc này là chỉnh sửa tệp htaccess của wordpress

Tệp htaccess của bạn trong wordpress sẽ trông giống như thế này

<IfModule mod_rewrite.c>
Viết LạiEngine Trên
Viết lạiBase /blog/
RewriteRule ^index\.php$ - [L]
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
Quy tắc viết lại . /blog/index.php [L]

Đây sẽ là htaccess tồn tại bên trong bộ chứa docker wordpress

smac89 avatar
lá cờ cn
Cảm ơn câu trả lời của bạn. Thật vậy, sử dụng `WP_HOME` và `WP_SITEURL` sẽ là một cách để giải quyết vấn đề này, nhưng tôi muốn xem liệu nó cũng có thể được thực hiện bằng cách chỉ sử dụng apache, mod_proxy hay không, đó là lý do tại sao [câu trả lời] của tôi (https://serverfault.com /a/1075300/257206) cũng tồn tại.
Điểm:0
lá cờ cn

Ok tôi nghĩ rằng tôi đã tìm ra vấn đề.

Wordpress sử dụng hai biến để xác định:

  1. url nào dẫn đến vị trí trang wordpress của bạn (WP_HOME)
  2. url nào được sử dụng để tải tài nguyên cho trang wordpress của bạn (WP_SITEURL)

Điều đầu tiên tôi phải làm cho bộ chứa wordpress là đảm bảo rằng các url này khớp với url bộ chứa bên trong, tức là $BLOG_SERVER. Bởi vì tôi sử dụng docker-compose, thật dễ dàng để chèn url này bằng cách sử dụng các biến môi trường thông qua WORDPRESS_CONFIG_EXTRA tranh luận.

wordpress-blog:
  hình ảnh: wordpress:5
  phụ thuộc:
    - blog-db
  môi trường:
    WORDPRESS_DB_HOST: blog-db
    WORDPRESS_DB_NAME: blog
    WORDPRESS_DB_USER: wordpress
    WORDPRESS_DB_PASSWORD: wordpress
    WORDPRESS_CONFIG_EXTRA: |
      xác định ('WP_HOME', 'http://wordpress-blog');
      xác định ('WP_SITEURL', 'http://wordpress-blog');
  khối lượng:
    - wordpress:/var/www/html

Điều đó đã xong, bây giờ chúng ta có thể tập trung vào proxy.

Trước khi tôi đi theo con đường của proxy ngược hoàn toàn, tôi đã giả định rằng proxy bằng cách nào đó sẽ đảm nhận mọi yêu cầu cho /Blog/ và trả lại các trang từ trang web được ủy quyền trông như thể chúng được phục vụ trực tiếp từ wordpress. Một điều tôi không tính đến là giả định này cũng giả định trang kết xuất phía máy chủ.

Bắt đầu với cái mới Máy chủ ảo cấu hình, bây giờ nó trông như thế này:

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

Điều tiếp theo tôi phải làm để proxy này bắt đầu hoạt động như một proxy là thêm dòng này:

ProxyPreserveTắt máy chủ

Điều này đảm bảo rằng tất cả các phản hồi/yêu cầu chúng tôi nhận được từ wordpress không giống như chúng đến từ chúng tôi (proxy). Lý do cho điều này sẽ sớm trở nên rõ ràng khi chúng ta bắt đầu xử lý html ủy quyền.


tiếp theo Proxy Pass chỉ thị đã được chuyển ra khỏi Địa điểm container, và trực tiếp vào Máy chủ ảo.

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

Lý do cho điều này là bởi vì Địa điểm các khối đã khớp với các yêu cầu rất muộn và đôi khi / con đường chiến thắng trên /Blog/ con đường. Tôi cần nó đáng tin cậy hơn, vì vậy tôi quyết định tự chỉ định các proxy (tôi đã xem một ví dụ đây), sau đó sửa đổi các đường dẫn bên trong Địa điểm thùng đựng hàng.


Tại thời điểm này, proxy ngược bây giờ là đang làm việc! Tuy nhiên, html trong các trang có các liên kết trỏ đến url nội bộ của trang wordpress. Đây là nơi mod_proxy_html đến. Nó có thể được sử dụng để viết lại tất cả các liên kết trong html để trỏ đến proxy ngược. Bất cứ nơi nào nó tìm thấy một liên kết trỏ đến trang blog nội bộ, liên kết đó sẽ được thay thế bằng một liên kết sử dụng proxy ngược.

ProxyHTMLBật Bật
ProxyHTMLExtended On
ProxyHTMLURLMap "${BLOG_SERVER}/"
SetOutputFilter INFLATE;proxy-html;DEFLATE

Dòng cuối cùng có thể gây ra nút cổ chai vì về cơ bản, nó giải nén tải trọng từ trang blog, viết lại tất cả các url để trỏ đến proxy ngược, sau đó nén chúng lại. Nếu bạn không muốn điều này, một cách khác để thực hiện nó là sử dụng:

RequestHeader bỏ đặt Mã hóa chấp nhận

Ngay cả khi đã có tất cả những điều này, giải pháp vẫn chưa hoàn hảo vì bất kỳ tệp javascript nào được tải trên trang tạo yêu cầu tới trang web nội bộ sẽ không chuyển yêu cầu của chúng tới proxy.

Một giải pháp cho vấn đề này là sử dụng giải pháp đầu tiên được đề xuất bởi câu trả lời hiện tại về câu hỏi này, và thay đổi WP_SITEURL để trỏ trực tiếp đến proxy ngược.

Một giải pháp khác là sử dụng một Nhân viên phục vụ đến chặn yêu cầu mạng. Tôi thích giải pháp này vì nó không liên kết chặt chẽ trang blog với proxy ngược. Tôi có thể tưởng tượng rằng sẽ không quá xa vời nếu đưa nhân viên dịch vụ vào bất kỳ trang html nào được yêu cầu từ proxy và yêu cầu nhân viên dịch vụ đó chặn tất cả các yêu cầu khớp với url của trang blog nội bộ và thay thế chúng bằng url proxy ngược.

Tôi đã đi với cả hai. Sau nhiều lần cân nhắc, tôi nghĩ lưu trữ wordpress trong một tên miền phụ sẽ tốt hơn cho nhu cầu của tôi. Một cái gì đó như blog.example.com là những gì tôi có thể làm, nhưng nó sẽ hoạt động vào một ngày khác.


Tóm lại, proxy ngược rất khó triển khai đúng cách với apache. Tôi không biết liệu cỏ có xanh hơn ở bên nginx hay không, nhưng có lẽ một ngày nào đó chúng ta sẽ kiểm tra nó. Giải pháp mà tôi đang thực hiện dành cho nội dung chỉ dành cho phía máy chủ, vốn đã được chứng minh là một ứng cử viên hoàn hảo để được ủy quyền, nhưng tiếc là nội dung được tải động sẽ yêu cầu nhiều công việc hơn.

nguồn

Các mô-đun Apache được kích hoạt để ủy quyền html

LoadModule deflate_module modules/mod_deflate.so
LoadModule mô-đun xml2enc_module/mod_xml2enc.so
LoadModule proxy_html_module modules/mod_proxy_html.so

Đăng câu trả lời

Hầu hết mọi người không hiểu rằng việc đặt nhiều câu hỏi sẽ mở ra cơ hội học hỏi và cải thiện mối quan hệ giữa các cá nhân. Ví dụ, trong các nghiên cứu của Alison, mặc dù mọi người có thể nhớ chính xác có bao nhiêu câu hỏi đã được đặt ra trong các cuộc trò chuyện của họ, nhưng họ không trực giác nhận ra mối liên hệ giữa câu hỏi và sự yêu thích. Qua bốn nghiên cứu, trong đó những người tham gia tự tham gia vào các cuộc trò chuyện hoặc đọc bản ghi lại các cuộc trò chuyện của người khác, mọi người có xu hướng không nhận ra rằng việc đặt câu hỏi sẽ ảnh hưởng—hoặc đã ảnh hưởng—mức độ thân thiện giữa những người đối thoại.