Linux

[linux]C9sdk 시스템 서비스 등록하기 (systemd 등록)

 저번에 리눅스에 c9 ide를 설치해서 돌리는거까지 했었는데,


매번 쓸때마다 스크립트를 실행해줬어야 하는 번거로움 + 불편함이 있었다. 


시스템 서비스(systemd)로 등록해서 백그라운드로 돌리는걸 해보자.


되게 간단한 작업인데.. 몇군데에서 오랜 삽질이 있었다. 


우분투 버전 : 18.04 LTS


1. service 파일 생성


/etc/systemd/system/ 


위 디렉토리에 파일을 생성해주어야 한다. 나같은경우는 아래와 같은 명령어를 실행했다. 


sudo vi /etc/systemd/system/c9sdk.service 


( 파일 생성 완료.)


2. 파일 내용 작성


[Unit]

Description=C9 IDE server


[Service]

Type=simple

User=synod2

ExecStart=node /home/synod2/c9sdk/server.js --listen [serverip] -p 4242 -a [id]:[pw] -w /home/synod2/synod2


WorkingDirectory= /home/synod2/synod2


[Install]

WantedBy=default.target


Description 은 서비스에 대한 설명.


Type은 [simple|forking|oneshot|notify|dbus] 로 나눠지는데, 각각에 대한 설명은 다음과 같다.


simple : 서비스가 시작됨과 동시에 systemd가 유닛의 시작이 완료되었다고 판단한다. 

다른 유닛과 통신하기 위해 소켓을 사용하는 경우 이러한 설정을 사용하면 안된다.


forking : "자식 프로세스 생성이 완료되는 단계"까지를 systemd 가 시작이 완료되었다고 판단하게 된다. 

부모 프로세스를 추적할 수 있도록 PIDFile= 필드 옵션을 추가하여 PID 파일을 선언해 주어야 한다.


oneshot : "simple" 과 다소 유사하지만 단일 작업을 수행하는데 적합한 타입이다. 또한 실행 이후 해당 실행이 종료되더라도 RemainAfterExit=yes 옵션을 통해 유닛이 활성화 상태로 간주할 수 있다.


notify : "simple" 과 동일하다. 다만 유닛이 구동되면 systemd 에 시그널을 보낸다. 이때 시그널에 대한 내용은  libsystemd-daemon.so 에 선언 되어 있다.


dbus : DBUS 에 지정된 BusName 이 준비될때까지 대기한다. 즉 DBUS 준비가 완료된 이후 유닛이 시작되었다고 간주한다. 


사실 simple이랑 forking 을 제외하면 나머지 옵션들 설명은 잘 모르겠다..


User는 프로세스를 실행할 사용자명을 지정한다. 나같은 경우는 내 계정으로 지정해줬다. 


ExecStart 는 실행될 명령어를 그대로 입력해주면 된다. c9 실행시 사용하는 명령어를 동일하게 작성해주면 되는데, 

이때 node 뒤에 붙을 server.js 실행 경로는 절대경로로 지정해주지 않으면 workingdirecroty 경로에 + 되어 실행된다. 

내 첫번째 삽질 포인트. 절대경로로 지정을 해주지 않으니까 자꾸 실행파일 경로를 못읽어오더라. 

그 다음, 맨뒤에 -w 옵션에서 지정해줄 실행경로는 c9 첫실행할때 만든 workspace 경로로 해줘야된다. 


WorkingDirectory 는 해당 서비스가 어디서 실행될건지에 대해 경로를 지정해준다. 

이때 경로는 c9 첫실행할때 만든 workspace 경로로 해줘야된다.  안그러면 실행될때 경로 관련 변수 세팅이 잘못되어

c9 IDE 상에서 workspace가 제대로 안뜨거나, terminal 기본 실행 경로가 어긋날 수 있다.


Wantedby 는 systemctl enable 명령어가 실행될 때에 서비스 등록에 필요한 프로세스를 지정한다. 

즉, 어떤 프로세스에 종속되는지에 대한 종속성 검사 단계라고 한다. 

자세한 내용은 아래 참조 링크 블로그에... 나도 이 옵션은 잘 몰라서 기본값인 default로 지정해줬다. 



3. systemctl 실행


작성과 저장이 모두 끝났으면, 저장된 서비스를 로드하고 실행하는 과정이 필요하다.


systemctl daemon-reload 


새로 추가된 데몬들을 리로드 하는명령어. .service 파일을 수정하거나 새로 추가 할때마다 실행해줘야 되는 명령어다.

이걸 안하면 백날 restart해도 수정내용이 제대로 반영이 안되더라. (아니면 내가 잘못하고있었거나.)


systemctl enable c9sdk

systemctl start c9sdk


굳이 추가적인 설명 없이도 감이 오긴 했는데 , enable은 추가된 서비스를 허용하주는, 그러니까 서비스 목록에 추가해주는 명령어고

start는 해당 서비스를 시작한다는 뜻이다.


systemctl restart c9sdk 


서비스를 재 시작해야될때 사용하는 명령어다. daemon-reload랑 같이 제일 많이 입력한거같다. 


위 systemctl 은 사실상 service 명령어랑 동일하게 작동하니까, 

service c9sdk restart 와 같이 명령어 위치만 바꿔서 실행해주면 같은 동작을 한다.


서비스를 실행 한 다음 제대로 돌아가는지, 혹은 실행에 실패해서 오류 분석이 필요할땐 


systemctl stats s9sdk or service c9sdk status


로 서비스 상태를 점검하자. 오류코드만 잘 봐도 문제 해결이 수월해진다. 


서비스가 제대로 돌아가는지 보려면 ps -ef | grep c9 로 프로세스를 한번 확인해보자. 


(겁나게 잘돌아가고 있다.)




이제 브라우저로 가서 확인해보면 특별한 문제가 없는이상 잘 될거다 .


(실행이랑 접속도 잘 된다.)


별로 삽질할만한게 없는데서 삽질을 왕창해서 식나 소모가 좀 많았다...


추가로, 이렇게 한 상태에서 IPtime 공유기로 포트포워딩 설정까지 해주니까 외부에서도 내 서버로 접속이 가능했다. 


이렇게도 되나? 생각하고 해봤는데 되더라. 역시 세상에 안되는건 없는거같다.


이제 이거 쓸때마다 원격으로 붙을 필요는 없을거같다. 서버만 켜두면 되니까. 


*19.01.28 추가

실행시에 실행 경로가 정확하지 않다면서 오류가 발생하는 경우가 종종있다.

exec format error 라던가, node 실행 명령어 관련 오류이다. 상대경로를 인식하지 못해 발생하는 문제.

그럴때는 /home/synod2//.nvm/v0.10.33/bin/node 를 경로로 node를 실행해주자.


*19.02.24 추가

서비스 실행시에 서비스가 뚜렷한 에러 없이 종료되면서 systemctl status로 보면 203 exit code를 뱉는 경우가 있다. (16.04버전에서 발생.)

이럴때는 ExecStart= 구문 앞에 /bin/bash를 붙여주면 정상 실행 된다. 

참고 자료 : https://stackoverflow.com/questions/45776003/fixing-a-systemd-service-203-exec-failure-no-such-file-or-directory


참고 자료 : http://fmd1225.tistory.com/93 

# systemd에 관해 몇몇 사용 안한 옵션이나, 옵션에 대한 자세한 설정은 위 링크를 참조하면 될 것 같다.