EC2实例上Laravel项目CSS、图片等静态文件加载失败求助
Laravel静态文件404问题排查与Nginx配置调整
问题背景
在EC2实例部署Laravel项目后,CSS、图片等静态文件实际存在于对应路径,但访问时返回404错误。
项目目录结构
/project /app /bootstrap /public /frontend /common /css main.css main-rtl.css index.php
当前Nginx配置
server { listen 80; root /home/ubuntu/websites/farmersdirect.lk/public_html/public; index index.html index.htm index.php; server_name dev.farmersdirect.lk test.ersdirect.lk; error_log /home/ubuntu/websites/farmersdirect.lk/logs/error.log; location ~ \.php$ { try_files $uri /index.php =404; fastcgi_split_path_info ^(.+\.php)(/.+)$; fastcgi_pass unix:/run/php/php8.2-fpm.sock; fastcgi_index index.php; fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name; include fastcgi_params; } location = /favicon.ico { access_log off; log_not_found off; } location = /robots.txt { access_log off; log_not_found off; } location / { proxy_pass http://127.0.0.1:8000; proxy_http_version 1.1; proxy_set_header Upgrade $http_upgrade; proxy_set_header Connection 'upgrade'; proxy_set_header Host $host; proxy_cache_bypass $http_upgrade; try_files $uri $uri/ /index.php?$query_string; } #add_header 'Access-Control-Allow-Methods' 'GET, POST, OPTIONS'; add_header X-XSS-Protection "1; mode=block"; add_header X-Content-Type-Options nosniff; #add_header Strict-Transport-Security 'max-age=31536000; includeSubDomains; preload'; add_header X-Frame-Options "SAMEORIGIN"; #add_header Content-Security-Policy "frame-ancestors 'self';"; location ~ /\.(?!well-known).* { deny all; access_log off; log_not_found off; } location ~* /(?:uploads|files|wp-content|wp-includes|akismet)/.*.php$ { deny all; access_log off; log_not_found off; } }
问题根源
反向代理与静态文件处理冲突:
location /中同时配置了proxy_pass http://127.0.0.1:8000和try_files,导致所有请求(包括静态文件)被转发到8000端口。如果8000是Artisan Serve临时服务,它对静态文件的路径处理逻辑和Nginx直接托管不一致,会引发404;而Laravel项目通过Nginx直接托管时,根本不需要反向代理,Nginx可直接返回静态文件。静态文件被错误拦截:
location ~ /\.(?!well-known).*规则会拦截所有包含点号的请求路径(比如/frontend/common/css/main.css),直接返回禁止访问,这是静态文件无法加载的直接原因。该规则原本应仅拦截以点开头的敏感隐藏文件(如.env、.git),而非所有带点的文件。
配置调整方案
1. 移除不必要的反向代理
删除location /中的proxy_pass相关配置,保留Laravel路由核心处理规则:
location / { try_files $uri $uri/ /index.php?$query_string; }
2. 修正隐藏文件拦截规则
将过严的拦截规则修改为仅拦截敏感隐藏文件,避免影响静态文件:
# 仅拦截以点开头的敏感隐藏文件/目录 location ~ /\.(env|git|htaccess|gitignore)$ { deny all; access_log off; log_not_found off; }
调整后的完整Nginx配置
server { listen 80; root /home/ubuntu/websites/farmersdirect.lk/public_html/public; index index.html index.htm index.php; server_name dev.farmersdirect.lk test.ersdirect.lk; error_log /home/ubuntu/websites/farmersdirect.lk/logs/error.log; location ~ \.php$ { try_files $uri /index.php =404; fastcgi_split_path_info ^(.+\.php)(/.+)$; fastcgi_pass unix:/run/php/php8.2-fpm.sock; fastcgi_index index.php; fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name; include fastcgi_params; } location = /favicon.ico { access_log off; log_not_found off; } location = /robots.txt { access_log off; log_not_found off; } location / { try_files $uri $uri/ /index.php?$query_string; } #add_header 'Access-Control-Allow-Methods' 'GET, POST, OPTIONS'; add_header X-XSS-Protection "1; mode=block"; add_header X-Content-Type-Options nosniff; #add_header Strict-Transport-Security 'max-age=31536000; includeSubDomains; preload'; add_header X-Frame-Options "SAMEORIGIN"; #add_header Content-Security-Policy "frame-ancestors 'self';"; # 仅拦截敏感隐藏文件 location ~ /\.(env|git|htaccess|gitignore)$ { deny all; access_log off; log_not_found off; } location ~* /(?:uploads|files|wp-content|wp-includes|akismet)/.*.php$ { deny all; access_log off; log_not_found off; } }
后续操作
- 保存修改后的Nginx配置文件
- 执行
nginx -t验证配置语法正确性 - 执行
systemctl reload nginx使配置生效
内容的提问来源于stack exchange,提问作者Rasathurai Karan
相关产品推荐
相关产品推荐

