You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

使用PHP-FPM和Docker部署Symfony时出现404 File not found问题求助

部署Symfony应用时遇到404 File not found错误

从昨天开始部署Symfony应用到个人服务器(拥有全部权限,但Linux相关知识有限),已将服务器8002端口映射到容器9000端口,Docker日志显示请求已到达容器,但所有请求均返回404 File not found错误,所有端点均出现该问题。

配置文件

subdomain.conf

<VirtualHost *:80>
    ServerName mysubdomain.domain.com
    ServerAlias www.mysubdomain.domain.com

    # Redirect to HTTPS
    RewriteEngine on
    RewriteCond %{SERVER_NAME} =mysubdomain.domain.com [OR]
    RewriteCond %{SERVER_NAME} =www.mysubdomain.domain.com
    RewriteRule ^ https://%{SERVER_NAME}%{REQUEST_URI} [END,NE,R=permanent]
</VirtualHost>

<VirtualHost *:443>
    ServerName mysubdomain.domain.com
    ServerAlias www.mysubdomain.domain.com

    # Proxy settings
    ProxyPreserveHost On
    ProxyPass / fcgi://localhost:8002/
    ProxyPassReverse / fcgi://localhost:8002/

    DocumentRoot /var/www/html/project/project-back/public
    DirectoryIndex /index.php

    # Allow .htaccess overrides in the public directory
    <Directory /var/www/html/project/project-back/public>
        AllowOverride All
        Options FollowSymLinks
        Require all granted
    </Directory>


    ErrorLog ${APACHE_LOG_DIR}/mysubdomain.domain.com-error.log
    CustomLog ${APACHE_LOG_DIR}/mysubdomain.domain.com-access.log combined

    # Enable SSL
    SSLEngine on
    SSLCertificateFile /some/path
    SSLCertificateKeyFile /some/path
    Include /some/path

    # Optionally enable HSTS to force browsers to use HTTPS
    Header always set Strict-Transport-Security "max-age=31536000; includeSubDomains"
</VirtualHost>

Dockerfile

# Use the official PHP 8.1 FPM image as the base
FROM php:8.1-fpm

# Set the working directory inside the container
WORKDIR /var/www/html

# Install system dependencies
RUN apt-get update && apt-get install -y \
    git \
    unzip \
    nano \
    net-tools \
    lsof \
    libpq-dev \
    libzip-dev \
    && docker-php-ext-install pdo pdo_mysql zip

# Install Composer
RUN curl -sS https://getcomposer.org/installer | php -- --install-dir=/usr/local/bin --filename=composer

# Copy project files into the container
COPY . .

# Set permissions for cache and log directories
RUN chmod -R 777 /var/www/html/var/cache /var/www/html/var/log

# Set permissions for cache and log directories
RUN chmod -R 777 /var/www/html/public

# Install Symfony dependencies
RUN composer install --no-dev --optimize-autoloader

# Expose PHP-FPM port
EXPOSE 9000

# Start PHP-FPM
CMD ["php-fpm", "-F"]

docker-compose.yaml

services:
  php:
    build:
      context: .
      dockerfile: ./Dockerfile
    container_name: mycontainer
    volumes:
      - .:/var/www/html
      - ./public:/var/www/html/public
    working_dir: /var/www/html
    ports:
      - "8002:9000"
    networks:
      - database


networks:
  database:
    external: true

调试信息

数据库网络连接正常,已在其他项目中使用。

最初mysubdomain.domain.com-error.log中存在警告:

[proxy:warn] AH01144: No protocol handler was valid for the URL / (scheme 'fcgi'). If you are using a DSO version of mod_proxy, make sure the proxy submodules are included in the configuration using LoadModule.

已通过sudo a2enmod proxy_fcgi解决该警告,但现在访问子域名时会出现404 File not found错误。

服务器端命令输出

$ curl https://mysubdomain.domain.com/
File not found.
$ curl -I https://mysubdomain.domain.com/
HTTP/1.1 404 Not Found
Date: Sat, 30 Nov 2024 14:48:08 GMT
Server: Apache/2.4.62 (Debian)
X-Powered-By: PHP/8.1.31
Content-Type: text/html; charset=UTF-8
$ curl -I http://localhost:8002
curl: (52) Empty reply from server
$ sudo docker logs mycontainer
NOTICE: fpm is running, pid 1
NOTICE: ready to handle connections
"GET /" 404
"GET /" 404
"GET /" 404
"GET /" 404

容器内部命令输出

# curl -I http://localhost:9000
curl: (56) Recv failure: Connection reset by peer
netstat -tlnp | grep 9000
tcp6       0      0 :::9000                 :::*                    LISTEN      1/php-fpm

补充说明:遇到的不是普通的“404 page not found”,而是“404 File not found”,所有页面都只显示这个内容,没有其他错误日志。

解决方案

核心问题分析

这个File not found是PHP-FPM返回的,原因是Apache传递给FPM的文件路径在容器内不存在:Apache的DocumentRoot指向服务器本地的/var/www/html/project/project-back/public,但容器内的项目路径是/var/www/html/public,两者路径不匹配,导致FPM找不到请求对应的文件。同时,直接用ProxyPass / fcgi://localhost:8002/的写法无法正确传递PHP文件的路径信息。

修复步骤

  1. 修改Apache配置文件subdomain.conf
    在VirtualHost *:443块中,替换原有的Proxy相关配置,改用ProxyPassMatch来正确映射容器内的文件路径:

    # 替换原有ProxyPass/ProxyPassReverse配置
    # 仅转发PHP请求到FPM,并映射到容器内的正确路径
    ProxyPassMatch ^/(.*\.php(/.*)?)$ fcgi://localhost:8002/var/www/html/public/$1
    
    # 静态文件直接从本地目录提供(提升性能)
    DocumentRoot /var/www/html/project/project-back/public
    <Directory /var/www/html/project/project-back/public>
        AllowOverride All
        Options FollowSymLinks
        Require all granted
    
        # Symfony前端控制器转发规则,处理非文件请求
        RewriteEngine On
        RewriteCond %{REQUEST_FILENAME} !-f
        RewriteRule ^(.*)$ /index.php [QSA,L]
    </Directory>
    
  2. 清理Docker重复Volume映射
    修改docker-compose.yaml,移除重复的./public映射(因为.:/var/www/html已经包含了public目录):

    volumes:
      - .:/var/www/html
    # 移除 - ./public:/var/www/html/public
    
  3. 优化容器权限(可选但推荐)
    修改Dockerfile中的权限设置,避免使用过高的777权限,改用www-data用户权限:

    # 替换原有的chmod命令
    RUN chown -R www-data:www-data /var/www/html/var /var/www/html/public
    RUN chmod -R 755 /var/www/html/var /var/www/html/public
    
  4. 重启服务并重建容器

    # 重启Apache
    sudo systemctl restart apache2
    
    # 重建并启动容器
    docker-compose down && docker-compose up -d --build
    

完成以上步骤后,重新访问子域名即可正常加载Symfony应用。

内容的提问来源于stack exchange,提问作者Anis B.

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.15 20:24:53