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

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,提问作者김형태

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.29 19:25:33