![让 Nginx 代理上的 WordPress 与子目录协同工作](https://linux22.com/image/1617001/%E8%AE%A9%20Nginx%20%E4%BB%A3%E7%90%86%E4%B8%8A%E7%9A%84%20WordPress%20%E4%B8%8E%E5%AD%90%E7%9B%AE%E5%BD%95%E5%8D%8F%E5%90%8C%E5%B7%A5%E4%BD%9C.png)
我正在尝试使用 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: