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

Laravel 8生产部署异常:除/外路由均Nginx 404,资源需带index.php访问

生产服务器部署Laravel 8路由404及静态资源加载问题

问题现象

  • 完成Laravel 8安装、迁移后,仅根路由/可访问,其他路由均返回Nginx 404错误
  • 首页仅在URL中添加/index.php时,样式和脚本才能正常加载

目录结构

htdocs
--public
    --app
    --bootstrap
    --public
    --.htaccess             
    --...

当前.htaccess规则

RewriteEngine On
RewriteRule ^(.*)$ public/$1 [L]

配置文件内容

Nginx配置(nginx.conf)

server {
    listen 80;
    server_name domain.com www.domain.com;

    include letsencrypt.conf;

    location / {
        root  /srv/www/domain.com/htdocs/public;
        index index.php index.html index.htm;
        try_files $uri $uri/ /index.php$is_args$args;

    }

    access_log off;
    error_log /srv/www/domain.com/logs/domain.com-err;
}

server {
    listen 443 ssl;
    server_name domain.com www.domain.com;
    #charset    utf-8;
    server_name_in_redirect off;

    if ($host ~ www.domain.com) { rewrite ^ https://example.com$request_uri? permanent; }

    ssl_certificate /etc/letsencrypt/live/domain.comfullchain.pem;
    ssl_certificate_key /etc/letsencrypt/live/domain.com/privkey.pem;

    access_log off;
    #access_log /srv/www/domain.com/logs/domain.com-acc main;
    error_log /srv/www/domain.com/logs/domain.com-err;

    proxy_set_header    X-Real-IP $remote_addr;
    proxy_set_header    X-Forwarded-For $proxy_add_x_forwarded_for;
    proxy_set_header    X-Forwarded-Proto $scheme;
    proxy_set_header    Host $host;

    set $proxyserver    "http://127.0.0.1:8080";
    set $imcontenttype  "text/html; charset=utf-8";
    set $docroot        "/srv/www/domain.com/htdocs/public";

    index index.php;
    root /srv/www/domain.com/htdocs/public;

    # Include parameters common to all websites
    include bx/bitrix.conf;
}

Apache配置(apache.conf)

<VirtualHost *>
    DocumentRoot /srv/www/domain.com/htdocs/public
    ServerName domain.com
    ServerAlias www.domain.com
    ErrorLog /srv/www/domain.com/logs/domain.com-err
    # CustomLog /srv/www/domain.com/logs/domain.com-acc combined
    <IfModule mod_setenvif.c>
        SetEnvIf X-Forwarded-Proto https HTTPS=on
    </IfModule>

        <IfModule mpm_itk_module>
                AssignUserID domain.com domain.com
        </IfModule>

        <IfModule mpm_prefork_module>
                RMode config
                RUidGid domain.com domain.com
                RGroups apache
        </IfModule>

    <Location />
        php_admin_value open_basedir "none"
        php_admin_value upload_tmp_dir "/srv/www/domain.com/tmp"
        php_admin_value session.save_path "/srv/www/domain.com/tmp"
        php_admin_value upload_max_filesize "256M"
        php_admin_value post_max_size "256M"
        php_admin_value memory_limit "512M"
        php_admin_value date.timezone "UTC"
        php_admin_value max_input_vars "10000"
        php_admin_value pcre.recursion_limit "100000"
        php_admin_value realpath_cache_size "4096k"
        php_admin_value mbstring.internal_encoding "utf-8"
        php_admin_value mbstring.func_overload "0"
    php_admin_value opcache.revalidate_freq "0"
        php_admin_value opcache.max_accelerated_files "100000"
        php_admin_value opcache.memory_consumption "256"
        #php_admin_flag short_open_tag "On"
    </Location>

    <DirectoryMatch .*\.svn/.*>
         Require all denied
    </DirectoryMatch>

    <DirectoryMatch .*\.git/.*>
         Require all denied
    </DirectoryMatch>

    <DirectoryMatch .*\.hg/.*>
         Require all denied
    </DirectoryMatch>

    <Directory /srv/www/domain.com/htdocs/public>
        Options Includes FollowSymLinks
        AllowOverride All
        Require all granted
    </Directory>

    <Directory /srv/www/domain.com/htdocs/public/bitrix/cache>
        AllowOverride none
        Require all denied
    </Directory>

    <Directory /srv/www/domain.com/htdocs/public/bitrix/managed_cache>
        AllowOverride none
        Require all denied
    </Directory>

    <Directory /srv/www/domain.com/htdocs/public/bitrix/local_cache>
        AllowOverride none
        Require all denied
    </Directory>

    <Directory /srv/www/domain.com/htdocs/public/bitrix/stack_cache>
        AllowOverride none
        Require all denied
    </Directory>

    <Directory /srv/www/domain.com/htdocs/public/upload>
        AllowOverride none
        AddType text/plain php,php3,php4,php5,php6,phtml,pl,asp,aspx,cgi,dll,exe,ico,shtm,shtml,fcg,fcgi,fpl,asmx,pht
        php_value engine off
    </Directory>

    <Directory /srv/www/domain.com/htdocs/public/upload/support/not_image>
        AllowOverride none
        Require all denied
    </Directory>

    <Directory /srv/www/domain.com/htdocs/public/bitrix/images>
        AllowOverride none
        AddType text/plain php,php3,php4,php5,php6,phtml,pl,asp,aspx,cgi,dll,exe,ico,shtm,shtml,fcg,fcgi,fpl,asmx,pht
        php_value engine off
    </Directory>

    <Directory /srv/www/domain.com/htdocs/public/bitrix/tmp>
        AllowOverride none
        AddType text/plain php,php3,php4,php5,php6,phtml,pl,asp,aspx,cgi,dll,exe,ico,shtm,shtml,fcg,fcgi,fpl,asmx,pht
        php_value engine off
    </Directory>

    <IfModule mod_rewrite.c>
        #Nginx should have "proxy_set_header HTTPS YES;" in location
        RewriteEngine On
        RewriteCond %{HTTP:HTTPS} =YES
        RewriteRule .* - [E=HTTPS:on,L]
    </IfModule>

</VirtualHost>

已尝试的解决方法

  • 按照Laravel 8官方文档配置Nginx,无效
  • 将Nginx和Apache的根目录改为htdocs/public/public,静态资源加载恢复正常,但路由仍返回404错误
  • 调整Apache配置,未解决路由问题

更新说明

已将Nginx和Apache配置中的根目录修改为/srv/www/domain.com/htdocs/public/public,静态资源可正常加载,但所有非根路由依然返回Nginx 404错误。


解决方案

1. 修正Nginx 443端口server块配置

当前443端口的server块缺少正确的路由转发规则,且存在配置冲突,需根据实际运行模式调整:

模式一:Nginx直接处理PHP请求
server {
    listen 443 ssl;
    server_name domain.com www.domain.com;
    server_name_in_redirect off;

    # 修正www重定向目标
    if ($host ~ www\.domain\.com) { 
        rewrite ^ https://domain.com$request_uri? permanent; 
    }

    # 修正SSL证书路径缺失的斜杠
    ssl_certificate /etc/letsencrypt/live/domain.com/fullchain.pem;
    ssl_certificate_key /etc/letsencrypt/live/domain.com/privkey.pem;

    access_log off;
    error_log /srv/www/domain.com/logs/domain.com-err;

    # 根目录指向Laravel的核心public目录
    root /srv/www/domain.com/htdocs/public/public;
    index index.php index.html index.htm;

    location / {
        try_files $uri $uri/ /index.php$is_args$args;
    }

    # PHP请求处理规则(根据实际PHP版本调整socket路径)
    location ~ \.php$ {
        fastcgi_pass unix:/run/php/php7.4-fpm.sock;
        fastcgi_index index.php;
        fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
        include fastcgi_params;
    }
}
模式二:Nginx反向代理到Apache(8080端口)
server {
    listen 443 ssl;
    server_name domain.com www.domain.com;
    server_name_in_redirect off;

    if ($host ~ www\.domain\.com) { 
        rewrite ^ https://domain.com$request_uri? permanent; 
    }

    ssl_certificate /etc/letsencrypt/live/domain.com/fullchain.pem;
    ssl_certificate_key /etc/letsencrypt/live/domain.com/privkey.pem;

    access_log off;
    error_log /srv/www/domain.com/logs/domain.com-err;

    proxy_set_header    X-Real-IP $remote_addr;
    proxy_set_header    X-Forwarded-For $proxy_add_x_forwarded_for;
    proxy_set_header    X-Forwarded-Proto $scheme;
    proxy_set_header    Host $host;

    set $proxyserver    "http://127.0.0.1:8080";

    location / {
        proxy_pass $proxyserver;
        try_files $uri $uri/ /index.php$is_args$args;
    }
}

2. 修正Apache配置

确保Apache的DocumentRoot指向Laravel核心public目录,并启用重写规则:

DocumentRoot /srv/www/domain.com/htdocs/public/public

<Directory /srv/www/domain.com/htdocs/public/public>
    Options Includes FollowSymLinks
    AllowOverride All
    Require all granted
</Directory>

3. 清理冗余.htaccess规则

删除htdocs/public目录下自定义的.htaccess,保留Laravel自带的public/public/.htaccess即可,其自带的规则已覆盖路由转发需求:

<IfModule mod_rewrite.c>
    <IfModule mod_negotiation.c>
        Options -MultiViews -Indexes
    </IfModule>

    RewriteEngine On

    # Handle Authorization Header
    RewriteCond %{HTTP:Authorization} .
    RewriteRule .* - [E=HTTP_AUTHORIZATION:%{HTTP:Authorization}]

    # Redirect Trailing Slashes If Not A Folder...
    RewriteCond %{REQUEST_FILENAME} !-d
    RewriteCond %{REQUEST_URI} (.+)/$
    RewriteRule ^ %1 [L,R=301]

    # Send Requests To Front Controller...
    RewriteCond %{REQUEST_FILENAME} !-d
    RewriteCond %{REQUEST_FILENAME} !-f
    RewriteRule ^ index.php [L]
</IfModule>

4. 重启服务

修改配置后重启Nginx和Apache:

systemctl restart nginx
systemctl restart httpd # 或 apache2,根据系统环境调整

内容的提问来源于stack exchange,提问作者Андрей Чистяков

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.27 18:24:59