프로젝트를 진행하면서 빠르게 api
서버를 배포해야 할 일들이 많다.
예를 들자면 해커톤에 참여할 때라던지, 당장 나의 api
를 클라이언트 프로그래머가 사용해야 할 경우가 종종 있다.
API 서버를 테스트로 배포할 때는 주로 다음의 과정을 거친다.
상당히 번거로운 작업이 아닐 수 없다. 그래서 나는 이런 경우 주로 ec2
에 git을 설치하고, 서버에 직접 repository를 만든 다음 ec2의 repo push하면 post receive hook을 사용하여 빠른 배포를 진행했다. 다음의 링크와 같은 방법이다. DIY node.js server on Amazon EC2
하지만 이런 방법에는 큰 단점이 있다. 바로 server에 git을 직접 bare로 설치하는 방법이기 때문에 나중에 github으로 프로젝트를 관리하기 어려워진다는 점이다. 최근 AWS직원분들과 이야기를 나눌 기회가 있었는데 Github Webhook
에 대해서 말씀해 주셔서 알아보게 되었다.
여담으로, 처음에 “어떻게 빠른 배포를 진행할까?”에 대해서 생각하면서 Jenkins
, Travis
같은 빌드툴을 이용하고 그 다음 자동 배포 로직을 돌리면 어떨까 생각했는데 생각보다 빌드툴을 셋팅하기도 오래 걸렸기 때문에 간단한 테스트에는 적합하지 않았다. AWS Code Deploy
에서 테스트 프로젝트를 돌려보니 Blue Green
배포 방식이고 router를 재연결하는 방식이기 때문에 코드가 빨리 배포되지는 않아서 매우 짜증이 났다.
그래서 결국에 제일 간단한 방법인 Github Webhook
을 선택하였다.
Secret을 생략할 수 있지만 사실 매우 중요한 부분이다. SECRET을 설정하지 않는다면 서버에서는 어떤 Post Request에도 Shell Script나 커맨드 또는 Logic을 무조건 실행하므로 보안상 배우 취약할 수 있다.
Nginx 설정을 진행한다.
$ vi /etc/nginx/sites-available/default
location /hook { // 이 부분이 포인트
proxy_pass http://127.0.0.1:3100/; //3100 포트로 proxy
}
설정 파일을 잠깐 살펴보면 /hook 으로 endpoint에 접속하면 3100번 포트로 proxy한다.
Github에 Push되었을 때 실행될 스크립트를 작성한다
$ mkdir ~/hook
$ vi ~/hook/hook.sh
코드를 설명하자면 Github Repository에 코드가 Push되었을때, 서버 디렉토리로 이동 후 Code를 Pull 받은 다음 pm2로 실행중인 기존의 서버를 재시작한다는 내용이다.
그 다음으로 Hook 폴더 내에서 $ npm init
을 한 후, start script를 작성한다. 추후에 pm2에 의해 nom start script가 실행된다.
$ vi ~/hook/package.json
{
"name": "hook",
"version": "1.0.0",
"description": "",
"main": "hook.js",
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1",
"start": "nodejs ./hook.js"
},
"author": "",
"license": "ISC"
}
Github에 Push 되었을때 이를 인지할 수 있는 작은 서버스크립트가 필요하다.
$ vi ~/hook/hook.js
코드를 설명하자면 Post Request가 왔을 때 클라이언트가 헤더에 x-hub-signature 값을 보내주는데, 이 값을 Server가 가지고 있는 토큰을 기반으로 Body를 암호화한 값과 같은지 보고 맞다면 아까 만들어둔 hook.sh를 실행한다는 내용이다.
여기서 중요한 점은 보안상의 이유로 위에서 진행했던 Secret Setting에 설정했던 키와 똑같은 키를 하드코딩된 변수가 아닌 환경변수(process.env[‘SCRET_TOKEN’]) 에서 불러와서 쓴다는 점이다.
SCRETTOKEN 환경변수는 다음과 같이 설정한다.
`$ echo export SECRETTOKEN=아까설정했던Secret >> ~/.bash_profile `
$ pm2 start npm --name="hook" -- start
이제 Background에서 Node.js 서버가 돌고있으면서 Post Request가 오기를 기다리고 있다.
Github Repo에 Push를 하면 Github이 우리 서버 URL(~~~/hook) 로 Post Request를 날리고, Nginx에서 이것을 3100 port로 proxy한다. 그러면 우리의 hook.js 서버에 도달하고 만약 SECRET이 일치한다면 hook.sh를 실행하고 불일치하면 실행하지 않는다.
npm start 커맨드를 pm2에서는 다음과 같이 실행한다.
빠르게 배포하기 위해서 Github Webhook에 대해서 알아봤다. Bash Script, SSH, PM2, Node.js 에 대해서 미리 어느 정도 알고 있다면 그렇게 어렵지는 않을 것이다. 까먹지 않고 있으면 빠른 배포가 필요한 상황에서 매우 유용할 것 같다.