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,提问作者Андрей Чистяков
相关产品推荐
相关产品推荐

