github + ngrok + webhook 으로 편하게 라즈베리파이 코딩하기

github + ngrok + webhook 으로 편하게 라즈베리파이 코딩하기

라즈베리파이에서 vi editor로 프로그래밍 하는 것은 너무 불편하다. (1)vi나 nano를 쓰는데, 확실히 Sublime Text나 Visual Studio Code보다 불편하다. 그래서 코딩은 데스크탑에서 하고 그걸 라즈베리파이로 옮기는 편이 더 수월하다. 근데 또 (2)자잘한 수정사항이 생길때마다 라즈베리파이로 매번 옮기는것도 귀찮다. 라즈베리파이로 뭘 해보려는 사람들이 공통적으로 느끼는 불편함이 아닐까 싶다. 이런 문제들을 ngrok과 webhook을 통해 해결할 수 있다.

(참고로 이 글에서는 github에 프로젝트 올리기 / 라즈베리파에서 clone / git 명령어에 대한것들은 다루지 않기 때문에 어느정도 git에대한 기초 지식이 있어야 합니다)

목차

  1. ngrok사용하기(링크)
  2. webhook이란?
  3. Github에서 Webhook설정
  4. Webhook의 이벤트를 받는 Node.js 서버 구축
  5. Boot될때 서버가 자동으로 실행되도록 설정
  6. 테스트

Webhook이란?

webhook은 어떤 이벤트가 발생할때 http notification을 목적지에 보내는 것이다. 지금 우리같은 경우는 심플하게 보면 아래와 같은 시나리오를 가진다.

  1. 노트북에서 코드 수정 및 commit
  2. github에 변경사항 push
  3. github은 내 라즈베리파이에 코드가 변경됬다는 메세지를 보낸다

Github에서 Webhook설정

위와같이 내 repository -> Settings -> Webhooks들어가서, Add webhook버튼을 누른다.

Payload URL => ngrok에서 할당받은 주소를 입력한다(ex. http://mysubdomain.ngrok.io).
Current type => JSON
Secret => 비밀번호 입력. 나중에 webhook으로 날라온 http notification이 진짜 자신의 깃헙에서 온건지 라즈베리파이(받는쪽)에서 확인할때 쓰인다.
Which events would you like to trigger this webhook ? => Send me everything

(위같이 설정해 주면 일반적으로 잘 되겠지만, 상황에 따라서 Current type이나, event같은 경우에는 다르게 설정해 줘야할것 같다.)

자! 이제 내가 git push ~~를 해주면 webhook이 알아서 ngrok을 통해 내 라즈베리파이로 http notification을 보낸다. 다만, 이렇게 notification이 온다한들 이걸 받아주는 서버가 없으면 아무런 의미가 없다.

Webhook의 이벤트를 받는 Node.js 서버 구축

http notification가 라즈베리파이로 날라왔고 우리는 이때 github에 코드를 달라고 요청해야한다. 이렇게 하려면 http notification을 기다리는 서버가 필요하다.

Node.js 서버 구축

Node.js가 이미 라즈베리파이에 설치되어있다고 가정한다. home 폴더에 webhook이라는 폴더를 하나 더 만든다. 그안에 index.js를 만들고 아래와 같이 입력한다.

// /home/내계정아이디/webhook/index.js

const secret = '아까 github의 webhook에서 설정한 비밀번호';

let http = require('http');
let crypto = require('crypto');

// 실제 git pull ~~ 하는 코드들을 node서버가 돌리게 되면 single thread특성상 서버가 잠깐 얼어버릴 수 있기 때문에 github에서 업데이트된 코드를 가져오는 일(git pull ~~)은 다른 child process에서 실행되도록 한다.
const exec = require('child_process').exec;

http.createServer(function(req, res){
  console.log( 'webhook.js is running : ' );
  req.on('data', function(chunk){
    let sig = "sha1=" + crypto.createHmac('sha1', secret).update(chunk.toString()).digest('hex');
    if (req.headers['x-hub-signature'] == sig) {
      deploy(res);
    } else {
      console.log('un matched');
    }
  });
  res.end();
}).listen(8080); // ngrok이 forwarding해주는 포트를 사용해야한다.

function deploy(res){
  // /home/pi/webhook => pi는 내 계정이름이기 때문에 실제로 쓸때는 본인의 맞는 path를 입력해 줘야한다.
  // deploy.sh안에는 github에서 업데이트된 코드를 가져오는 git pull ~~ 명령어가 들어있는 shell script(?) 파일이다
  exec('/home/pi/webhook/deploy.sh', function(err, stdout, stderr){
    console.log('deploy.sh is called');
    if (err) {
      console.error(err);
      res.writeHead(404);
      return res.end();
    }
    res.writeHead(200);
    res.end();
  });
}

deploy.sh 파일 작성

cd /home/내계정아이디/git이설치된 프로젝트 폴더

echo "Pulling from Master"

git pull origin master

echo "Pulled successfully from master"

// 이제 새로 코드를 가져왔으니까 자신의 프로젝트에 맞게 무언가를 해주면 된다.

이제 이 deploy.sh파일을 아까 만든 webhook폴더에 넣으면 된다.

Boot될때 서버가 자동으로 실행되도록 설정

아까전에 라즈베리파이를 키자마자 ngrok이 자동으로 시작되게 해놓았듯이 이 Node서버도 자동으로 시작되게 하면 편하다. 방법은 이 글에서 설명한다.

테스트

이제 자신의 컴퓨터에서 코드를 수정하고 -> Commit -> Push 하고나서 github의 webhook 설정 페이지에 ngrok 도메인으로 잘 갔는지 확인해 본다.

또 라즈베리파이에서는 git의 log를 보고 새 코드로 업데이트가 잘 됬는지 확인해 본다.

참고

  1. https://github.com/inconshreveable/ngrok/issues/345
  2. https://github.com/vincenthsu/systemd-ngrok
  3. https://medium.com/@andrew.nease.code/set-up-a-self-booting-node-js-eb56ebd05549

마지막으로

처음엔 좀 복잡하지만 해놓고 나면 분명히 편할것입니다. 긴 글 읽어주셔서 감사하고, 어려운점이나 잘못된 내용이 있으면 댓글로 남겨주시기 바랍니다.

댓글 남기기

이메일은 공개되지 않습니다. 필수 입력창은 * 로 표시되어 있습니다

Up Next:

모니터 키보드 없이 라즈베리파이 제어하기

모니터 키보드 없이 라즈베리파이 제어하기