Ubuntu服务器Apache代理Node.js应用出现503 Service unavailable错误
Ubuntu Apache反向代理Node.js Todo应用出现503错误的解决思路
问题概述
我在Ubuntu服务器部署Node.js开发的Todo应用,本地localhost:3000运行正常,但通过Apache反向代理(8080端口)访问时出现503 Service Unavailable错误,排查后确定是res.sendFile加载HTML页面的流程导致问题。
应用本地运行逻辑
- 访问根路径时,通过以下代码返回HTML页面:
app.get("/", (req, res) => { res.sendFile(__dirname+"/public/index.html") }); - HTML加载后调用
loadTodos(),通过fetch('http://localhost:3000/todos')从MongoDB获取任务数据 - 编辑、添加、删除操作同理,通过fetch对应路由完成数据交互
Apache配置情况
已启用代理模块,/etc/apache2/ports.conf添加Listen 8080,虚拟主机配置:
<VirtualHost *:8080> ProxyPreserveHost on ProxyPass / http://localhost:3000/ ProxyPassReverse / http://localhost:3000/ </VirtualHost>
服务器文件结构
/var/www/nodejs --app.js --package-lock.json --package.json --node_modules --public ---code.js ---index.html ---style ----styles.css
解决步骤
1. 确认Node应用是否正常运行
- 执行
ps aux | grep node查看Node进程是否存在,若未运行则启动应用:cd /var/www/nodejs && npm start - 在服务器本地执行
curl http://localhost:3000,验证Node应用是否能正常返回HTML内容,若这一步失败,优先排查Node应用本身的问题
2. 修正res.sendFile的路径问题
__dirname在不同部署环境下可能出现路径偏差,改用path模块构建绝对路径更可靠:
- 在
app.js顶部引入path模块:const path = require('path'); - 修改根路由的处理代码:
app.get("/", (req, res) => { res.sendFile(path.join(__dirname, 'public', 'index.html')); });
3. 检查文件权限
确保Apache和Node进程的运行用户能读取public目录及文件:
- 查看Node进程运行用户:
ps aux | grep node(第一列即为用户) - 查看Apache运行用户:
ps aux | grep apache2(通常为www-data) - 设置目录权限:
sudo chown -R www-data:www-data /var/www/nodejs/public sudo chmod -R 755 /var/www/nodejs/public - 若Node运行用户不是
www-data,可将其加入该组:sudo usermod -aG www-data [你的Node运行用户名]
4. 修正前端fetch请求地址
前端code.js中使用的绝对地址http://localhost:3000/todos,在服务器部署后会导致浏览器请求本地而非服务器的Node应用,需改为相对路径:
async function loadTodos() { let response = await fetch('/todos') // 去掉域名,使用相对路径 let todos = await response.json() console.log(todos) showTodos(todos) }
其他编辑、添加、删除的fetch请求也需同步改为相对路径。
5. 验证Apache代理配置
- 确认代理模块已启用:
sudo a2enmod proxy proxy_http sudo systemctl restart apache2 - 检查虚拟主机配置是否已启用:将配置文件放在
/etc/apache2/sites-available后,执行sudo a2ensite [你的配置文件名],再重启Apache - 查看Apache错误日志定位细节:
sudo tail -f /var/log/apache2/error.log
内容的提问来源于stack exchange,提问作者Talar
相关产品推荐
相关产品推荐

