Amazon Linux2 EC2上Nginx+Passenger部署Node.js项目无法访问文件
AWS EC2 Amazon Linux2 部署Node.js+Passenger+Nginx无法访问问题排查
问题描述
在AWS EC2的Amazon Linux2微型实例上部署Node.js项目,已安装Phusion Passenger和Nginx并以Passenger Nginx模式运行。启动Nginx后访问服务器IP无法获取文件,路径确认正确,已执行chmod -R 755权限设置,手动创建/var/log/nginx目录及access.log、error.log,但error.log为空,access.log仅显示浏览器控制台的错误信息。已开放目录及/home/ec2-user的其他用户执行权限,问题依旧。项目server.js代码如下:
import http from "http"; import SocketIO from "socket.io" import express from "express"; const app = express(); app.set("view engine", "pug"); app.set("views", __dirname + "/views"); app.use("/public", express.static(__dirname + "/public")); app.use("/speech", express.static(__dirname + "/speech")); app.use('/images', express.static(__dirname + '/images')); app.use('/models', express.static(__dirname + '/models')); app.use(express.json()) app.use(express.urlencoded({extended: true})) app.post('/submit', (req,res) => { var sentence1 = req.body.sentence; var left_eyes = (req.body.left_eyes); var right_eyes = (req.body.right_eyes); const obj ={sentence : sentence1}; var sentence = JSON.stringify(obj); console.log(sentence); const fs = require('fs'); fs.writeFileSync("test.txt", sentence); fs.writeFileSync("left_eyes.txt", left_eyes); fs.writeFileSync("right_eyes.txt", right_eyes); res.sendFile(__dirname +'/views/test2.html') }) app.get('/submit2', (req,res) => { var sentence = req.query.sentence; console.log(sentence); const fs = require('fs'); fs.writeFileSync("test.txt", sentence); res.sendFile(__dirname +'/views/test.html') }) app.get('/getEyearray',(req,res)=>{ const fs = require('fs'); var data1 = fs.readFileSync('right_eyes.txt', (err,data) => {}); var data2 = fs.readFileSync('left_eyes.txt', (err,data) => {}); var data = { right: JSON.parse(data1), left: JSON.parse(data2)}; res.send(data); }) app.get('/eyesresult', (req,res)=>{ res.render("eyeresult"); }) app.post('/convert', (req,res)=>{ const fs = require('fs'); var data = fs.readFileSync('test.txt', (err,data) => {}); var dataParsed = JSON.parse(data); res.writeHead(200, {'Content-Type': 'text/html;charset=UTF-8'}); var openApiURL = "http://aiopen.etri.re.kr:8000/WiseNLU_spoken"; var access_key = '725aebde-323a-4964-a231-ccde25bae07e'; var analysisCode = 'ner'; var text = ''; text += dataParsed.sentence; var requestJson = { 'argument': { 'text': text, 'analysis_code': analysisCode } }; var request = require('request'); var options = { url: openApiURL, body: JSON.stringify(requestJson), headers: {'Content-Type':'application/json','Authorization':access_key} }; request.post(options, function (error, response, body) { res.write(body); }); }) app.get("/test2", (req, res) => res.sendFile(__dirname +'/views/test2.html')); app.get("/", (req, res) => res.sendFile(__dirname +'/views/test.html')); app.use(express.urlencoded({extended: true})); app.get('/home', (req,res)=>{ res.render('home') }) app.get('/interview', (req,res)=>{ res.sendFile(__dirname +'/views/interview.html') }) app.get('/join', (req, res) => { res.render("join"); }) app.get('/login', (req,res)=>{ res.sendFile(__dirname +'/views/login.html') }) app.get('/interview2', (req,res)=>{ res.sendFile(__dirname +'/views/interview2.html') }) app.get('/annyang', (req,res)=>{ res.sendFile(__dirname +'/views/annyang.html') }) const httpServer = http.createServer(app); const wsServer = SocketIO(httpServer); function openRooms(){ let roomNum = roomObjArr.length; const openrooms = []; for(let i=0; i<roomNum; i++){ const name_count = []; name_count.push(roomObjArr[i].roomName); name_count.push(roomObjArr[i].currentNum); openrooms.push(name_count); } return openrooms; } let roomObjArr = [ ]; const MAXIMUM = 4; wsServer.on("connection", (socket) => { let myRoomName = null; socket["nickname"] = "Anon"; socket.emit("room_change", openRooms()); socket.on("join_room", (roomName) => { myRoomName = roomName; let isRoomExist = false; let targetRoomObj = null; for(let i = 0; i<roomObjArr.length; ++i) { if (roomObjArr[i].roomName === roomName) { if(roomObjArr[i].currentNum >= MAXIMUM) { socket.emit("reject_join"); ++roomObjArr[i].currentNum; return; } isRoomExist = true; targetRoomObj = roomObjArr[i]; break; } } if (!isRoomExist) { targetRoomObj = { roomName, currentNum: 0, users: [], }; roomObjArr.push(targetRoomObj); } targetRoomObj.users.push({ socketId: socket.id, }); ++targetRoomObj.currentNum; socket.join(roomName); wsServer.sockets.emit("room_change", openRooms()); socket.emit("welcome", targetRoomObj.users); }); socket.on("offer", (offer, remoteSocketId) => { socket.to(remoteSocketId).emit("offer", offer, socket.id); }); socket.on("answer", (answer, remoteSocketId) => { socket.to(remoteSocketId).emit("answer", answer, socket.id); }); socket.on("ice", (ice, remoteSocketId) => { socket.to(remoteSocketId).emit("ice", ice, socket.id); }); socket.on("new_message", (msg, room, done) => { socket.to(room).emit("new_message", `${socket.nickname}: ${msg}`); done(); }); socket.on("nickname", (nickname) => (socket["nickname"] = nickname)); socket.on("disconnecting", () => { socket.to(myRoomName).emit("leave_room", socket.id); let isRoomEmpty = false; for(let i = 0; i< roomObjArr.length; i++){ if(roomObjArr[i].roomName === myRoomName){ const newUsers = roomObjArr[i].users.filter( (user) => user.socketId != socket.id ); roomObjArr[i].users = newUsers; --roomObjArr[i].currentNum; if (roomObjArr[i].currentNum == 0) { isRoomEmpty = true; } } } if (isRoomEmpty) { const newRoomObjArr = roomObjArr.filter( (roomObj) => roomObj.currentNum != 0 ); roomObjArr = newRoomObjArr; } }); socket.on("disconnect", () => { if(roomObjArr.length == 0){ wsServer.sockets.emit("room_change2"); } else{ wsServer.sockets.emit("room_change", openRooms()); } }); }); const handleListen = () => console.log("Listening on http://localhost:3000"); httpServer.listen(3000, handleListen); app.post('/login', (req,res)=>{ const {userid,userpw} = req.body; connection.query(`SELECT * FROM User WHERE userid="${userid}"`, (error, result) => { if (error) return console.log(error); if (result.length) { console.log(result); if (result[0].userpw === userpw) { console.log('login 성공'); } else { console.log('login 실패'); } res.redirect('/'); } else { console.log('login 실패'); res.redirect('/'); } }); res.sendFile(__dirname +'/views/login.html') }) app.post('/join', (req, res) => { const {name,userid,userpw,useremail,} = req.body; //mysql 삽입; var sql = `INSERT INTO User (userid, userpw, username, useremail) VALUES ('${name}','${userid}','${userpw}','${useremail}')`; connection.query(sql, function (err, result) { if (err) throw err; console.log("1 record inserted"); }); res.sendFile(__dirname + "/views/login.html") })
排查与解决方案
1. 修正Passenger Nginx核心配置
- 确保Nginx配置文件(通常在
/etc/nginx/conf.d/或/etc/nginx/sites-enabled/下)正确指向项目路径,配置示例:server { listen 80; server_name 你的服务器IP; root /home/ec2-user/你的项目根目录; passenger_enabled on; passenger_app_type node; passenger_startup_file server.js; passenger_nodejs /usr/bin/node; # 需确认Node.js实际路径 } - 配置修改后重启Nginx:
sudo systemctl restart nginx
2. 移除项目手动监听端口代码
Passenger会自动管理应用端口,无需项目自行监听localhost,注释或删除以下代码:
const handleListen = () => console.log("Listening on http://localhost:3000"); httpServer.listen(3000, handleListen);
3. 完善权限设置
- 确保项目目录所有者/组包含Nginx运行用户(通常为
nginx):sudo chown -R ec2-user:nginx /home/ec2-user/你的项目根目录 sudo chmod -R 755 /home/ec2-user/你的项目根目录 - 检查Nginx运行用户:
ps aux | grep nginx,确认用户具备项目目录访问权限
4. 查看Passenger专属日志
Nginx error.log为空时,错误通常输出到Passenger日志:
sudo tail -f /var/log/passenger.log
- 若项目无
tmp目录,需创建以存放应用stderr日志:mkdir -p /home/ec2-user/你的项目根目录/tmp sudo chmod -R 775 /home/ec2-user/你的项目根目录/tmp
5. 验证网络访问规则
- 确认EC2安全组开放80端口(HTTP)入站规则,允许目标IP访问
- 检查Amazon Linux2防火墙设置:
sudo firewall-cmd --add-service=http --permanent sudo firewall-cmd --reload
6. 修复代码潜在问题
connection变量未定义(登录/注册接口使用),需补充MySQL连接代码:const mysql = require('mysql'); const connection = mysql.createConnection({ host: 'localhost', user: '你的数据库用户', password: '你的数据库密码', database: '你的数据库名' }); connection.connect();- ES模块中
__dirname需手动定义,添加以下代码到文件顶部:import { fileURLToPath } from 'url'; import { dirname } from 'path'; const __filename = fileURLToPath(import.meta.url); const __dirname = dirname(__filename);
内容的提问来源于stack exchange,提问作者김형태
相关产品推荐
相关产品推荐

