You need to enable JavaScript to run this app.
最新活动
大模型
产品
解决方案
定价
生态与合作
支持与服务
开发者
了解我们

使用Docker Compose配置Apache多虚拟主机(FPM)遇404错误求助

解决Apache虚拟主机配置404问题(主站+子路径WordPress)

让我来帮你排查下问题,你的配置里有几个关键问题导致了访问时出现“Not Found”错误,咱们一步步来修正:

1. 核心问题分析

  • 重复的ServerName:你创建了两个VirtualHost都用了www.mysite.com作为ServerName,Apache会优先匹配第一个加载的虚拟主机,导致另一个的规则完全不生效,这是404的主要原因。
  • 错误的路径代理逻辑:WordPress FPM容器的根目录是/var/www/html,但你当前的ProxyPassMatch/blog/xxx.php代理到了blog:9000/var/www/html/$1,这里的$1blog/xxx.php,相当于找容器里的/var/www/html/blog/xxx.php,但WordPress的文件都在根目录,自然找不到。
  • 过时的Docker Compose语法links已经被弃用了,建议用networks来保证服务间的连通性。

2. 修正Docker Compose配置

先更新你的docker-compose.yml,改用networks确保所有服务在同一个网络内,同时完善WordPress的环境变量配置:

version: '3.8'
volumes:
  webroot:
  dbdata:
  wpdbdata:

networks:
  app-network:
    driver: bridge

services:
  server:
    build: ./docker/apache
    image: server:latest
    networks:
      - app-network
    ports:
      - 80:80
      - 443:443
    volumes:
      - webroot:/var/www/html/mysite.com
      # 可选:如果想让Apache直接处理WordPress静态文件,加快速度,添加下面的挂载
      # - wp-static:/var/www/html/blog/wp-content
  fpm:
    build: ./docker/php
    image: fpm:latest
    networks:
      - app-network
    depends_on:
      - database
    volumes:
      - webroot:/var/www/html/mysite.com
  database:
    build: ./docker/mariadb
    image: database:latest
    env_file:
      - ./docker/mariadb/env
    networks:
      - app-network
    volumes:
      - dbdata:/var/lib/mysql
  wpdatabase:
    image: mysql:latest
    networks:
      - app-network
    volumes:
      - wpdbdata:/var/lib/mysql
    environment:
      MYSQL_ROOT_PASSWORD: your-root-password
      MYSQL_DATABASE: wordpress
      MYSQL_USER: wordpress-user
      MYSQL_PASSWORD: wordpress-pass
  blog:
    image: wordpress:4.9.1-php7.1-fpm-alpine
    networks:
      - app-network
    depends_on:
      - wpdatabase
    environment:
      WORDPRESS_DB_HOST: wpdatabase:3306
      WORDPRESS_DB_USER: wordpress-user
      WORDPRESS_DB_PASSWORD: wordpress-pass
      WORDPRESS_DB_NAME: wordpress
    # 配合上面的可选挂载,把WordPress静态文件共享出来
    # volumes:
    #   - wp-static:/var/www/html/wp-content

3. 修正Apache虚拟主机配置

把两个VirtualHost合并成一个,通过路径匹配分别代理主站和/blog的请求,同时处理静态文件和PHP:

<VirtualHost *:80>
  ServerName www.mysite.com
  ServerAlias mysite.com
  ServerAdmin webmaster@localhost
  DocumentRoot /var/www/html/mysite.com

  # 处理主站的PHP请求(排除/blog路径)
  ProxyPassMatch ^/(?!blog)(.*\.php(/.*)?)$ fcgi://fpm:9000/var/www/html/mysite.com/$1 timeout=120

  # 方案1:如果挂载了WordPress静态文件,直接让Apache处理
  # Alias /blog/wp-content /var/www/html/blog/wp-content
  # <Directory /var/www/html/blog/wp-content>
  #   Require all granted
  #   Options FollowSymLinks MultiViews
  # </Directory>

  # 方案2:如果没挂载静态文件,用反向代理把静态文件请求转发到WordPress容器
  ProxyPass /blog/wp-content http://blog:80/wp-content
  ProxyPassReverse /blog/wp-content http://blog:80/wp-content

  # 处理/blog路径的PHP请求:把/blog/xxx.php代理到容器的/var/www/html/xxx.php
  ProxyPassMatch ^/blog/(.*\.php(/.*)?)$ fcgi://blog:9000/var/www/html/$1 timeout=120

  # 设置/blog的默认首页
  <Location /blog>
    DirectoryIndex index.php
  </Location>

  ErrorLog /usr/local/apache2/logs/error.log
  CustomLog /usr/local/apache2/logs/access.log combined
</VirtualHost>

4. 确保Apache启用必要模块

在你的Apache Dockerfile里,要启用代理相关的模块,否则配置不会生效:

FROM httpd:2.4
RUN apt-get update && apt-get install -y \
    libapache2-mod-proxy-html \
    libxml2-dev \
&& a2enmod proxy proxy_fcgi proxy_http rewrite headers

# 复制你的虚拟主机配置到Apache的配置目录
COPY ./vhost.conf /usr/local/apache2/conf/extra/httpd-vhosts.conf
# 在主配置里包含虚拟主机配置
RUN echo "Include conf/extra/httpd-vhosts.conf" >> /usr/local/apache2/conf/httpd.conf

5. 配置WordPress站点URL

最后,要确保WordPress知道它的外部访问路径是/blog,可以通过两种方式设置:

  • 登录WordPress后台,在「设置」→「常规」里,把「站点地址(URL)」和「WordPress地址(URL)」都改成http://www.mysite.com/blog
  • 如果暂时无法访问后台,可以在WordPress容器的wp-config.php里添加:
define('WP_HOME','http://www.mysite.com/blog');
define('WP_SITEURL','http://www.mysite.com/blog');

做完这些后,重启Docker Compose服务,应该就能正常访问主站和/blog路径了。

内容的提问来源于stack exchange,提问作者javal88

火山引擎 最新活动