웹 개발
systemd 서비스가 시작 안 될 때
개인 프로젝트를 서버에서 자동으로 실행하려고 systemd 서비스를 만들었는데, 시작해도 바로 죽거나 로그에 에러만 뜹니다.
systemd 서비스를 만들었는데 systemctl start myapp을 실행하면 금방 종료된다. 로그를 봐도 뭐가 문제인지 모르겠다.
서비스 상태 확인
먼저 서비스가 어떤 상태인지 본다.
sudo systemctl status myapp
# 세부 정보
sudo systemctl status myapp -l
# 로그 보기
sudo journalctl -u myapp -n 50
Active: failed 상태면 문제가 있다. 로그에서 에러를 찾는다.
서비스 파일 확인
serviceice 파일이 제대로 작성됐는가? /etc/systemd/system/myapp.service를 본다.
[Unit]
Description=My App
After=network.target
[Service]
Type=simple
User=app
WorkingDirectory=/home/app/myapp
ExecStart=/usr/bin/node /home/app/myapp/index.js
Restart=always
RestartSec=10
[Install]
WantedBy=multi-user.target
흔한 실수:
ExecStart의 경로가 잘못됨User가 존재하지 않음WorkingDirectory가 없음- 실행 권한 없음
직접 명령 실행해보기
서비스 파일의 ExecStart 명령을 서비스 User로 직접 실행해본다.
# app 사용자로 실행
sudo -u app /usr/bin/node /home/app/myapp/index.js
여기서 에러가 나면 문제가 뭔지 명확하다. 예:
Permission denied: 파일 접근 권한 없음Cannot find module: 패키지를 설치하지 않음Port 3000 already in use: 포트가 이미 사용 중
로그 상세히 보기
# 마지막 100줄 로그
sudo journalctl -u myapp -n 100
# 실시간 로그
sudo journalctl -u myapp -f
# 특정 시간대 로그
sudo journalctl -u myapp --since "2024-06-30 10:00:00"
환경 변수 설정
Node.js 앱이 NODE_ENV나 포트 같은 환경 변수를 필요하면 서비스 파일에 설정한다.
[Service]
Environment="NODE_ENV=production"
Environment="PORT=3000"
Environment="DATABASE_URL=postgres://..."
ExecStart=/usr/bin/node /home/app/myapp/index.js
파일 권한 확인
서비스가 쓰는 디렉토리와 파일에 권한이 있는가?
# 소유권 확인
ls -la /home/app/myapp
# app 사용자가 소유한가?
sudo chown -R app:app /home/app/myapp
# 쓰기 권한이 필요하면
sudo chmod -R u+w /home/app/myapp
포트와 방화벽
앱이 포트 3000을 쓴다면, 그 포트가 여유 있는가?
# 포트 사용 확인
sudo ss -lntp | grep 3000
# 방화벽 규칙 확인
sudo ufw status
sudo ufw allow 3000
systemd 서비스 다시 로드
서비스 파일을 수정하면 systemd를 다시 로드해야 한다.
# 데몬 재로드
sudo systemctl daemon-reload
# 서비스 다시 시작
sudo systemctl restart myapp
최종 확인: 수동 테스트
서비스로 시작 안 되면 수동으로 시작해본다.
# 터미널에서 직접 실행
cd /home/app/myapp
NODE_ENV=production /usr/bin/node index.js
# 이게 성공하면 서비스 파일 설정 문제
# 이것도 실패하면 앱 자체 문제
Systemd는 좋은 도구지만, 처음에는 복잡하다. 서비스 파일을 만들 때는 일단 수동으로 실행해서 에러를 없애고, 그다음 서비스로 자동화한다.