Nginx部署PHP+Node.js项目时访问出现404 Cannot GET /错误的排查求助
Nginx部署PHP+Node.js项目时访问出现404 Cannot GET /错误的排查求助
兄弟,我仔细看了你的配置和问题描述,马上就发现了核心问题——你的Nginx主域名配置把所有请求都直接代理到了Node.js的8000端口,但你的Node.js服务(server.js)根本没处理任何HTTP路由,只开了WebSocket监听,所以访问主域名时,Node.js找不到对应的GET /路由,自然返回404了!
下面是一步步的修复方案:
一、修正Nginx核心配置(关键!)
你的主server块(监听80/443)现在完全把请求甩给了Node.js,但你的PHP站点其实在8080端口的server块里,这完全搞反了。应该让主域名指向PHP站点,单独代理WebSocket请求到Node.js。修改你的lapignatomarseille.com.conf:
server { listen 80; listen [::]:80; listen 443 ssl http2; listen [::]:443 ssl http2; server_name lapignatomarseille.com www.lapignatomarseille.com; ssl_certificate /etc/letsencrypt/live/lapignatomarseille.com/fullchain.pem; ssl_certificate_key /etc/letsencrypt/live/lapignatomarseille.com/privkey.pem; ssl_trusted_certificate /etc/letsencrypt/live/lapignatomarseille.com/chain.pem; ssl_stapling on; ssl_stapling_verify on; # 主站点指向PHP项目根目录 root /home/lapignatomarseille/htdocs/lapignatomarseille.com; try_files $uri $uri/ /index.php?$args; index index.php index.html; # PHP处理规则 location ~ \.php$ { include fastcgi_params; fastcgi_intercept_errors on; fastcgi_index index.php; fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name; try_files $uri =404; fastcgi_read_timeout 3600; fastcgi_send_timeout 3600; fastcgi_param HTTPS "on"; fastcgi_param SERVER_PORT 443; fastcgi_pass 127.0.0.1:18001; fastcgi_param PHP_VALUE " error_log=/home/lapignatomarseille/logs/php/error.log; memory_limit=512M; max_execution_time=60; max_input_time=60; max_input_vars=10000; post_max_size=64M; upload_max_filesize=64M; date.timezone=Europe/Paris; # 替换UTC+1为标准时区名更规范 display_errors=off;"; } # 单独代理WebSocket请求到Node.js的8000端口 location /ws { proxy_http_version 1.1; proxy_pass http://localhost:8000; proxy_set_header Host $host; 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; # WebSocket必须的升级头 proxy_set_header Upgrade $http_upgrade; proxy_set_header Connection "upgrade"; proxy_cache_bypass $http_upgrade; } } # 不需要8080端口的备用站点的话,直接删除整个8080的server块
二、调整Node.js的WebSocket配置
为了配合Nginx的/ws路径代理,修改server.js里的socketIO配置,指定匹配路径:
const express = require('express'); const http = require('http'); const socketIO = require('socket.io'); const fs = require('fs'); const cors = require('cors'); const app = express(); app.use(cors()); const server = http.createServer(app); // 新增path参数,和Nginx的代理路径对应 const io = socketIO(server, { cors: { origin: 'https://lapignatomarseille.com', methods: ['GET', 'POST'], credentials: true }, path: '/ws' // 关键:指定WebSocket的路径 }); // 后续WebSocket逻辑保持不变 io.on('connection', (socket) => { console.log('Un client s\'est connecté'); fs.watch('Images', { recursive: true }, (eventType, filename) => { if (eventType === 'change' || eventType === 'rename') { io.emit('imageUpdated', { filename }); setTimeout(function() {io.emit('MenuOk',{ filename });}, 500); } }); socket.on('disconnect', () => { console.log('Un client s\'est déconnecté'); }); }); const PORT = process.env.PORT || 8000; server.listen(PORT, () => { console.log(`Serveur HTTP démarré sur le port ${PORT}`); });
三、修正客户端的WebSocket连接地址
原来的客户端连接是本地端口,现在要改成主域名的/ws路径,适配HTTPS:
<script> // 改成主域名的WebSocket路径,自动适配HTTPS环境 const socket = io.connect('https://lapignatomarseille.com', { path: '/ws' }); socket.on('connect', (e) => { console.log('Client connecté '); }); socket.on('imageUpdated', (data) => { console.log('Image mise à jour:', data.filename); // 按需保留或注释页面刷新逻辑 document.location.reload() }); </script>
四、补充日志排查建议
你之前只看了Nginx的error.log,这些日志也能帮你定位问题:
- Nginx访问日志:路径一般是
/var/log/nginx/access.log,能看到请求的具体路径、状态码、来源IP,确认请求是否被正确转发 - Node.js日志:启动Node.js的终端会直接输出日志,也可以把日志写入文件:
node server.js > /var/log/nodejs/server.log 2>&1 - PHP错误日志:你配置的路径是
/home/lapignatomarseille/logs/php/error.log,PHP站点的问题会在这里记录
最后,修改完配置后记得重启服务:
# 重启Nginx sudo systemctl restart nginx # 重启Node.js(如果用pm2管理的话) pm2 restart server.js # 没有pm2的话,先杀掉原有进程再重新启动
这样调整后,主域名会正常访问你的PHP站点,WebSocket请求会通过/ws路径转发到Node.js服务,应该就能解决404问题了!
备注:内容来源于stack exchange,提问作者HowYouDoIt
相关产品推荐
相关产品推荐

