让 Nginx 代理上的 WordPress 与子目录协同工作

让 Nginx 代理上的 WordPress 与子目录协同工作

我正在尝试使用 WordPress 官方 Docker 容器来提供内容https://example.com/blog。Nginx 实例位于 WordPress 前面,处理所有 SSL 相关事务。Nginx 配置如下:

upstream example-blog {
        server 127.0.0.1:4000 fail_timeout=30s;
}

...
server {
        server_name example.com; # managed by Certbot

        location / {
                proxy_connect_timeout   300;
                proxy_send_timeout      300;
                proxy_read_timeout      300;
                send_timeout            300;
                proxy_redirect          off;
                proxy_set_header        Host                    $host;
                proxy_set_header        X-Forwarded-Host        $host;
                proxy_set_header        X-Forwarded-Server      $host;
                proxy_set_header        X-Real-IP               $remote_addr;
                proxy_set_header        X-Forwarded-For         $proxy_add_x_forwarded_for;
                proxy_set_header        X-Forwarded-Protocol    $scheme;
                proxy_set_header        X-Forwarded-Proto       $scheme;
                proxy_pass              http://example-server;
        }

        location /blog {
                proxy_connect_timeout   300;
                proxy_send_timeout      300;
                proxy_read_timeout      300;
                send_timeout            300;
                proxy_redirect          off;
                proxy_set_header        Host                    $host;
                proxy_set_header        X-Forwarded-Host        $host;
                proxy_set_header        X-Forwarded-Server      $host;
                proxy_set_header        X-Real-IP               $remote_addr;
                proxy_set_header        X-Forwarded-For         $proxy_add_x_forwarded_for;
                proxy_set_header        X-Forwarded-Protocol    $scheme;
                proxy_set_header        X-Forwarded-Proto       $scheme;
                proxy_pass              http://example-blog;
        }

        listen [::]:443 ssl ipv6only=on; # managed by Certbot
        listen 443 ssl; # managed by Certbot
        ssl_certificate /etc/letsencrypt/live/example.com/fullchain.pem; # managed by Certbot
        ssl_certificate_key /etc/letsencrypt/live/example.com/privkey.pem; # managed by Certbot
        include /etc/letsencrypt/options-ssl-nginx.conf; # managed by Certbot
        ssl_dhparam /etc/letsencrypt/ssl-dhparams.pem; # managed by Certbot

}

server {
    if ($host = example.com {
        return 301 https://$host$request_uri;
    } # managed by Certbot
    listen 80 ;
    listen [::]:80 ;
    server_name example.com;
    return 404; # managed by Certbot
}

有一个 Python Flask 实例,为其下的位置提供服务/(这可以正常工作)。

我的docker-compose.yml样子是这样的:

version: '3.3'

services:
   db:
     image: mysql:5.7
     volumes:
       - db_data:/var/lib/mysql
     restart: always
     environment:
       MYSQL_ROOT_PASSWORD: <redacted>
       MYSQL_DATABASE: wordpress
       MYSQL_USER: wordpress
       MYSQL_PASSWORD: <redacted>

   wordpress:
     depends_on:
       - db
     build: .
     ports:
       - "127.0.0.1:4000:80"
     restart: always
     environment:
       WORDPRESS_DB_HOST: db:3306
       WORDPRESS_DB_USER: wordpress
       WORDPRESS_DB_PASSWORD: <redacted>
       WORDPRESS_DB_NAME: wordpress
       WORDPRESS_CONFIG_EXTRA: |
                               define('WP_HOME', 'https://example.com/blog');
                               define('WP_SITEURL', 'https://example.com/blog');
volumes:
    db_data: {}

Dockerfile 如下所示:

FROM wordpress:latest

COPY docker-entrypoint.sh /usr/local/bin/docker-entrypoint.sh

docker-entrypoint.sh是来自库存 wordpress 图像的一个,添加了以下内容:

if [[ ! -z ${WORDPRESS_CONFIG_EXTRA+x} ]]; then
        sed -i -e "/stop editing/i ${WORDPRESS_CONFIG_EXTRA//$'\n'/\\n}" wp-config.php
fi

使其使用的内容,WORDPRESS_CONFIG_EXTRA正如wp-config.php文档(错误地)声称的那样。

第一次启动并尝试访问时example.com/blog,我被重定向到https://example.com/blog/wp-admin/install.php,然后进入重定向循环。根据 Firefox 的说法,该 HTTPS 地址会重定向到其自身,并且确实docker logs wordpress_wordpress_1会出现一大堆这样的内容:

172.27.0.1 - - [26/Feb/2020:17:15:41 +0000] "GET /blog/wp-admin/install.php HTTP/1.0" 302 349 "-" "Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:73.0) Gecko/20100101 Firefox/73.0"

因此,这不是 nginx 的 HTTP 处理程序和 wordpress 之间的请求乒乓问题;而是 wordpress 将重定向返回到其自身。

有人能告诉我如何解决这个问题吗?

答案1

在您的位置块中尝试

proxy_set_header        X-Forwarded-Host $http_host;

$host通常等于$http_host,除非 $host 等于处理请求的服务器的 server_name 指令的值 - 并且不同(即正则表达式)(Nginx 中 $host 和 $http_host 有什么区别

在您的 WordPress 配置中,请确保将 SSL http 标头设置为$_SERVER['HTTPS']='on';

答案2

初始化WordPress 的在类似的子目录中/blog,您可以使用working_dir属性。

默认WordPress 的图像/var/www/html用途/var/www/html/blog,此时您可以转至进行初始化。

# ...
  wordpress:
    image: wordpress:apache
    working_dir: /var/www/html/blog
    volumes:
      - ./data/blog:/var/www/html/blog/wp-content
      - ./blog/wp-config.php:/var/www/html/blog/wp-config.php
# ...

现在您可以导航至http://localhost/blog

完整示例

以下是完整docker-compose.yml示例:

version: '3.1'

x-wordpress: &wordpress
  depends_on:
    - db
  environment:
    WORDPRESS_DB_HOST: db:3306
    WORDPRESS_DB_NAME: wordpress
    WORDPRESS_DB_USER: wordpress
    WORDPRESS_DB_PASSWORD: wordpress
  working_dir: /var/www/html/blog
  volumes:
    - wp_root:/var/www/html/blog
    - ./wp-content/plugins:/var/www/html/blog/wp-content/plugins
    - ./wp-content/themes:/var/www/html/blog/wp-content/themes
    - ./wp-content/uploads:/var/www/html/blog/wp-content/uploads
    - ./wp-content/languages:/var/www/html/blog/wp-content/languages

services:
  # Database
  db:
    image: mysql:5.7
    volumes:
      - db_data:/var/lib/mysql
      - ./backup/blog.sql:/docker-entrypoint-initdb.d/dump.sql:ro
    ports:
      - 3306:3306
    environment:
      MYSQL_ROOT_PASSWORD: password
      MYSQL_DATABASE: wordpress
      MYSQL_USER: wordpress
      MYSQL_PASSWORD: wordpress

  # phpmyadmin
  phpmyadmin:
    depends_on:
      - db
    image: phpmyadmin/phpmyadmin
    ports:
      - 8080:80
    environment:
      PMA_HOST: db
      MYSQL_ROOT_PASSWORD: password

  # Wordpress
  wordpress:
    <<: *wordpress
    image: wordpress:apache
    ports:
      - 80:80

  wpcli:
    <<: *wordpress
    image: wordpress:cli

volumes:
  wp_root:
    driver_opts:
      type: tmpfs
      device: tmpfs
  db_data:

相关内容