Docker环境下Nginx多Location配置问题:路径跳转异常
问题:WordPress子路径重定向丢失端口导致404错误
我通过Docker Compose搭建了包含MySQL数据库、WordPress-FPM、Nginx的架构,用于部署Angular单页应用和WordPress博客功能。预期访问域名根路径显示Angular应用,访问domain_name/wptest路径显示WordPress,但实际访问http://server_address:8085/wptest时,会被重定向到不带端口的http://server_address/wptest,进而出现404错误。单独运行各应用时功能正常。
以下是相关输出和配置文件:
curl 输出
C:\Users\Lacwik>curl -v http://{server_address}:8085/wptest * Trying {server_address}:8085... * Connected to {server_address} ({server_address}) port 8085 > GET /wptest HTTP/1.1 > Host: {server_address}:8085 > User-Agent: curl/8.4.0 > Accept: */* > < HTTP/1.1 301 Moved Permanently < Server: nginx/1.25.3 < Date: Fri, 15 Dec 2023 11:41:36 GMT < Content-Type: text/html < Content-Length: 169 < Location: http://{server_address}/wptest/ < Connection: keep-alive < <html> <head><title>301 Moved Permanently</title></head> <body> <center><h1>301 Moved Permanently</h1></center> <hr><center>nginx/1.25.3</center> </body> </html> * Connection #0 to host {server_address} left intact
docker-compose.yaml
version: "3.7" services: db: image: mysql:5.7 container_name: db-mysql volumes: - ./persistence/db_data:/var/lib/mysql networks: - bridge_network environment: MYSQL_ROOT_PASSWORD: "${MYSQL_ROOT_PASSWORD}" MYSQL_DATABASE: "${MYSQL_DATABASE}" MYSQL_USER: "${MYSQL_USER}" MYSQL_PASSWORD: "${MYSQL_PASSWORD}" wordpress-fpm: image: wordpress:5-php7.4-fpm container_name: wp-fpm depends_on: - db volumes: - ./persistence/wp_files:/var/www/html networks: - bridge_network environment: WORDPRESS_DB_HOST: "${WORDPRESS_DB_HOST}" WORDPRESS_DB_NAME: "${WORDPRESS_DB_NAME}" WORDPRESS_DB_USER: "${WORDPRESS_DB_USER}" WORDPRESS_DB_PASSWORD: "${WORDPRESS_DB_PASSWORD}" nginx: image: nginx container_name: nginx depends_on: - wordpress-fpm ports: - 8085:80 volumes: - ./persistence/nginx_conf:/etc/nginx/conf.d - ./persistence/wp_files:/var/www/html - ../frontend/dist:/var/www/frontend networks: - bridge_network volumes: db_data: wp_files: nginx_conf: networks: bridge_network: driver: bridge
nginx.conf
server { listen 80; listen [::]:80; # Serve Angular App location / { root /var/www/frontend/site; try_files $uri $uri/ /index.html; } # Proxy requests to /wptest to wordpress-fpm location ^~ /wptest { alias /var/www/html; try_files $uri $uri/ /wptest/index.php$is_args$args; location ~ \.php$ { include fastcgi_params; fastcgi_pass wordpress-fpm:9000; fastcgi_param SCRIPT_FILENAME $request_filename; fastcgi_param PATH_INFO $fastcgi_path_info; fastcgi_index index.php; } error_log /var/log/nginx/wptest_error.log; access_log /var/log/nginx/wptest_access.log; } }
问题原因
- WordPress重定向逻辑缺失端口信息:重定向是WordPress内部生成的,它无法感知外部访问使用的8085端口,因此生成的
Location头不包含端口,导致跳转后地址无效。 - Nginx未传递关键参数:当前Nginx配置没有向WordPress-FPM传递包含端口的
Host头及其他代理相关参数,导致WordPress无法正确识别外部访问地址。 - 路径匹配歧义:
location ^~ /wptest和alias /var/www/html的组合缺少末尾斜杠,可能引发路径解析不一致,间接触发WordPress的目录重定向逻辑。
解决办法
1. 调整Nginx配置
修改nginx.conf,补充必要参数并修正路径匹配:
server { listen 80; listen [::]:80; # Serve Angular App location / { root /var/www/frontend/site; try_files $uri $uri/ /index.html; } # Proxy requests to /wptest to wordpress-fpm location ^~ /wptest/ { alias /var/www/html/; try_files $uri $uri/ /wptest/index.php$is_args$args; location ~ \.php$ { include fastcgi_params; fastcgi_pass wordpress-fpm:9000; fastcgi_param SCRIPT_FILENAME $request_filename; fastcgi_param PATH_INFO $fastcgi_path_info; fastcgi_index index.php; # 传递包含端口的Host信息给WordPress fastcgi_param HTTP_HOST $host:$server_port; fastcgi_param HTTPS $https if_not_empty; fastcgi_param SERVER_PORT $server_port; } error_log /var/log/nginx/wptest_error.log; access_log /var/log/nginx/wptest_access.log; } }
- 将
location ^~ /wptest改为location ^~ /wptest/,同时alias末尾添加斜杠,确保路径解析一致 - 添加
fastcgi_param HTTP_HOST $host:$server_port,让WordPress获取到正确的外部访问端口,生成带端口的重定向URL - 传递
HTTPS和SERVER_PORT参数,确保WordPress站点URL配置的准确性
2. 修正WordPress站点URL
如果Nginx配置调整后仍存在问题,需手动更新WordPress的站点URL:
方法1:通过MySQL命令行修改
- 进入MySQL容器:
docker exec -it db-mysql mysql -u root -p
- 切换到WordPress数据库:
USE ${MYSQL_DATABASE};
- 更新站点URL和首页URL:
UPDATE wp_options SET option_value = 'http://{server_address}:8085/wptest' WHERE option_name = 'siteurl'; UPDATE wp_options SET option_value = 'http://{server_address}:8085/wptest' WHERE option_name = 'home';
方法2:通过WordPress后台修改(可访问时)
进入WordPress后台→设置→常规,将"WordPress地址(URL)"和"站点地址(URL)"修改为http://{server_address}:8085/wptest
内容的提问来源于stack exchange,提问作者Lacwik
相关产品推荐
相关产品推荐

