为Node.js应用创建专用的日志目录(如/var/log/my-node-app),避免将日志存放在应用根目录(易引发权限冲突)。使用chown将目录所有者设置为运行Node.js的用户(如nodeapp),chmod设置目录权限为750(所有者可读写执行,组用户可读执行,其他用户无权限):
sudo mkdir -p /var/log/my-node-app
sudo chown nodeapp:nodeapp /var/log/my-node-app # 替换为你的应用用户
sudo chmod 750 /var/log/my-node-app
这一步确保Node.js进程有权限向目录中写入日志文件。
在应用代码中,使用日志库(如Winston)时,显式设置日志文件的权限为0o640(所有者可读写,组用户可读,其他用户无权限),避免默认权限过宽(如0o666):
const winston = require('winston');
const logger = winston.createLogger({
transports: [
new winston.transports.File({
filename: '/var/log/my-node-app/app.log',
mode: 0o640 // 关键:限制文件权限
})
]
});
若需动态创建目录,可在代码中添加检查:
const fs = require('fs');
const logDir = '/var/log/my-node-app';
if (!fs.existsSync(logDir)) {
fs.mkdirSync(logDir, { recursive: true, mode: 0o750 }); // 创建目录时设置权限
}
这一步从应用层确保日志文件的权限符合安全要求。
绝对禁止用root用户运行Node.js应用,应创建专用用户(如nodeapp)和组(如nodeapp),并将应用配置为以该用户身份运行:
sudo groupadd nodeapp
sudo useradd -g nodeapp -s /bin/false nodeapp # -s /bin/false禁止登录
若使用systemd管理服务(推荐),在服务文件(如/etc/systemd/system/my-node-app.service)中指定用户:
[Service]
User=nodeapp
Group=nodeapp
WorkingDirectory=/var/www/my-node-app
ExecStart=/usr/bin/node app.js
Restart=always
修改后需重新加载systemd并重启服务:
sudo systemctl daemon-reload
sudo systemctl restart my-node-app
这一步彻底避免因root权限导致的权限问题。
安装logrotate(Ubuntu默认预装),创建配置文件(如/etc/logrotate.d/my-node-app),设置日志轮转规则:每天轮转、保留7天、压缩旧日志、创建新日志时设置权限640:
/var/log/my-node-app/*.log {
daily
missingok
rotate 7
compress
delaycompress
notifempty
create 640 nodeapp nodeapp # 关键:新日志文件的权限与所有者
sharedscripts
postrotate
# 若使用systemd,通知应用重新打开日志文件
systemctl kill -s USR1 my-node-app.service
endscript
}
这一步防止日志文件过大占用磁盘空间,同时保持权限一致性。
setfacl为目录添加ACL权限(无需修改所有者):sudo setfacl -R -m u:nodeapp:rwx /var/log/my-node-app # 授予用户rwx权限
pm2 start app.js --uid nodeapp --gid nodeapp
并确保PM2日志目录权限正确:sudo chown -R nodeapp:nodeapp /home/nodeapp/.pm2
这一步解决PM2管理下的权限问题。通过以上步骤,可全面解决Ubuntu下Node.js日志的权限问题,既保证应用正常写入日志,又确保日志文件的安全性。