웹 개발
프로세스가 떠 있는데 로그가 쌓이지 않던 권한 문제
systemd 서비스의 실행 사용자와 로그 파일 소유자가 다르면서 조용히 기록되지 않던 상황을 해결한 기록.
상황
Node 서비스를 systemd로 돌리던 중에 요청이 간헐적으로 멈췄다. systemctl status는 active였고 포트도 열려 있었다. 이상했던 건 배포 시각 이후 로그 파일에 새 줄이 하나도 안 생겼다는 점이었다.
처음에는 앱 내부 에러라고 생각했지만, 실제로는 로그 파일을 만들었던 사용자가 root였고 서비스는 nodeapp 사용자로 실행되고 있었다. 파일에 쓸 수 없어서 에러 핸들러 안에서 다시 에러가 나는 구조였다.
서비스 설정 확인
먼저 서비스가 어떤 사용자로 떠 있는지 봤다.
systemctl show myapp -p User -p Group
ps -o user,group,pid,cmd -C node
그 다음 로그 디렉터리의 소유자와 권한을 확인했다.
namei -l /var/log/myapp/app.log
ls -l /var/log/myapp
namei -l을 쓰면 중간 디렉터리 권한까지 같이 보여서 좋았다. 파일만 보고 넘어가면 /var/log/myapp 디렉터리 권한을 놓치기 쉽다.
수정 방법
나는 로그 파일을 서비스 사용자에게 맞추는 쪽으로 정했다. 앱을 root로 올리는 건 피하고 싶었다.
sudo install -o nodeapp -g nodeapp -d /var/log/myapp
sudo touch /var/log/myapp/app.log
sudo chown nodeapp:nodeapp /var/log/myapp/app.log
sudo systemctl restart myapp
그리고 앱 시작 시 로그 디렉터리가 없으면 바로 실패하게 했다. 조용히 넘어가면 다음에 또 원인 찾기가 어려워진다.
다음 배포에서 놓치지 않으려고
- 서비스 실행 사용자와 파일 소유자가 같은가?
- 로그 디렉터리 실행 권한이 빠지지 않았는가?
- 배포 스크립트가 root로 빈 로그 파일을 만들지 않는가?
- 로그 쓰기 실패가 앱 전체를 멈추게 만들지 않는가?
정리
서버에서 권한 문제는 에러 메시지가 친절하지 않을 때가 많다. 프로세스가 살아 있다는 사실만 보고 안심하지 말고, 앱이 실제로 쓰는 파일까지 같은 사용자 기준으로 확인해야 한다.