지킬, 두레이, 람다로 팀블로그 만들기

매주 친구들과 IT 관련 서적을 정리하거나, 기술을 공부하고 작은 프로젝트를 만드는 showerbugs라는 모임을 3년째 운영하고 있습니다. 서적이나 기타 내용을 읽고 정리한 내용은 Dooray(두레이)라는 협업도구에 공유하고, 프로젝트를 위한 코드 저장소는 github을 이용하고 있습니다.

그러다 팀원들 끼리 공부한 내용을 외부에도 공유하자는 이야기가 나왔습니다. 두레이는 private한 협업 도구이기 때문에, 정리한 내용을 외부에 쉽게 공유하고자 팀블로그를 만들게 되었습니다.

이 글은, 기존의 내부 공유 도구인 두레이를 그대로 이용하면서 같은 데이터를 팀블로그에도 자동으로 쓸 수 있도록 만든 과정을 정리한 글입니다.

자동화 설계

요구사항은 간단했습니다.

“두레이에 글을 쓰면 두레이에서 제공하는 훅을 이용해 자동으로 팀블로그에 포스팅이 되게 하자. 단, Serverless 관련 기술을 이용한다.”

호스팅은 무료인데다가 사용하기 쉬운 깃헙 페이지, 정적 페이지 생성기는 깃헙에서 빌드를 지원해줘 퍼블리싱 과정을 더 단순하게 만들 수 있는 Jekyll을 사용했습니다. 훅을 받아 깃헙에 푸시할 서버리스 펑션은 AWS의 Lambda를 통해서 해결하기로 했습니다.

과정은 다음과 같습니다.

jekyll인 이유

어차피 git으로 받을 꺼면 지킬대신 hugo나 tinkerer같은 다른 언어로 된 정적 블로그 생성기를 쓰면 안될까? 지킬은 너무 느린데라고 의아해하는 분들이 있을지도 모르겠습니다. 다른 것도 가능하지만 가장 큰 이유는 github에서 지원하는 정적생성기이기 때문에 커밋해야할 파일을 .md하나로 최소화 할 수 있다는 점입니다.

hugo를 쓰려면 hugo를 설치해야합니다. 빌드하기 위해 그와 관련된 다른 lib도 받아야 합니다. 람다에서 정적블로그 생성기를 신경써야 합니다. 정적생성기와 관련된 코드가 들어가면서 파일자체도 커집니다. 또한, 빌드과정도 별도로 들어가고 생성된 html 파일또한 같이 커밋해야 합니다.

람다의 최대 실행시간은 5분입니다. 요금 또한 실행시간과 메모리 만큼 나갑니다. static 파일생성에 5분이 걸릴일은 없겠지만 시간을 최소화 할 수 있습니다.

jekyll은 루비긴 하지만 깃헙에서 유일하게 지원하는 블로그 엔진입니다. 즉 자동으로 깃헙에서 빌드를 해주기 떄문에 루비와 지킬을 람다에서 신경 쓸 필요가 없습니다. _post 폴더 하위에 md파일만 커밋하면 static html을 생성해줍니다.

두레이에 훅 등록하기

두레이?

먼저 두레이라는 툴을 설명해야 할 것 같은데요. 간단히 설명하면 이슈트래커, 메일, 켈린더 등을 한번에 쓸 수 있는 협업도구입니다. 저희는 그 중 이슈트래커인 프로젝트에 기록을 남기고 있었습니다. tui editor를 이용해 마크다운 포맷과 쉬운 이미지 삽입으로 이슈 관리를 편리하게 할 수 있습니다. Inline-image-2017-11-15 19.33.18.126.png

목록에 있는 하나하나의 항목을 ‘업무’라고 하는데요, 업무를 쓸 때 아래와 같이 외부로 훅을 날릴 수 있습니다.

Inline-image-2017-11-15 19.40.53.198.png

각 프로젝트 설정 화면에 있는 저 웹훅 추가 창에 람다와 API Gateway를 통해 만든 주소를 등록할 것입니다.

람다 함수 생성

등록은 너무 간단하고 설명하고 있는 사이트도 많아서 간단히 설명하겠습니다. 참고

먼저 람다함수를 만들고 Inline-image-2017-11-15 19.42.37.400.png

node-github을 쓸거라서 node(6.9.1)로 함수를 만듭니다. 기본으로 함수를 생성해 놓습니다. Inline-image-2017-11-15 20.05.20.021.png

간단히 테스틀 하면 성공합니다. Inline-image-2017-11-15 20.06.21.246.png

만든 람다 함수를 API로 만들기 위해서 Gateway에 등록을 해야합니다.

API Gateway 서비스에 들어가서 API 작성을 누르고 새 API를 만듭니다.

Inline-image-2017-11-15 19.46.55.386.png

작업 > 메소드 생성 > POST로 생성합니다. (웹훅인 만큼 POST를 사용합니다)

Inline-image-2017-11-15 19.47.37.562.png

‘Lambda 함수’를 선택하고 람다 함수의 이름을 입력합니다. (자동 완성이 됩니다) Inline-image-2017-11-15 19.50.06.531.png

작업 > API 배포를 클릭하여 API를 배포합니다. Inline-image-2017-11-15 19.57.56.195.png

스테이지를 만들고 스테이지 탭으로 이동합니다. Inline-image-2017-11-15 19.58.32.749.png

이제 드디어 호출 할 수 있는 URL이 나옵니다. Inline-image-2017-11-15 20.00.10.881.png

람다 함수의 트리거 탭에 가보면 게이트웨이가 잘 등록되어 있습니다. Inline-image-2017-11-15 20.15.07.339.png

이 URL을 아까 두레이 훅 url창에 입력하면 끝! 이제 훅을 받을 준비가 다 되었습니다.

블로그로 발행하기

람다를 통해 받은 내용을 블로그에 발행하려면, repo를 받은 다음에 푸쉬를 해야합니다. 다행히도 git은 람다 컨테이너에 이미 설치되어 있기 때문에, Github API의 node.js wrapper인 node-github만 따로 패키징해주면 됩니다.

커밋 코드 만들기

이제 람다 함수의 실제코드를 작성합니다. 람다 함수는 간단하게 AWS의 웹 에디터에서도 작성할 수 있지만 다른 node lib과 같이 쓰려면 (=require를 쓰겠다는 말과 같습니다) 해당 프로젝트를 압축해서 배포해야합니다.

Inline-image-2017-11-15 22.14.56.220.png

프로젝트의 구조는 다음과 같습니다.

index.js는 메인로직, account는 깃헙 계정 정보가 적혀 있고, doorayParser는 두레이 훅으로부터 받은 json 데이터를 md 파일로 바꿔줍니다.

index.js를 보겠습니다.

let githubapi = require('github'),
    doorayParser = require('./doorayParser');


exports.handler = (event, context, callback) => {
    //깃헙 인스턴스 생성 
    let github = new githubapi({version: "3.0.0"});
    
    let referenceCommitSha,
    newTreeSha, newCommitSha, code;

    //owner랑 repo를 변경하기 쉽게 node의 process변수에 저장합니다.
    const owner = process.env.ORG_NAME;
    const repo = process.env.REPO;
    
    //두레이 api를 파싱합니다.
    let blog = doorayParser(event);

    if(!blog) {
        console.log('This is not correct api');
        return;
    }
  
    //계정 정보를 초기화 합니다.
    github.authenticate(require("./account"));
    
    let commitMessage = 'Add from dooray ' + blog.fileName;
    
    ....이어서
    

위와 같이 초기화 과정을 거치면 준비가 완료됩니다. 저 위에서 process.ENV는 노드에서 리눅스 환경변수에 접근할 때 사용하는 변수의 이름으로 AWS의 람다-환경변수 탭에 가면 이렇게 시스템 환경변수를 설정할 수 있습니다. Inline-image-2017-11-15 22.37.48.863.png

이제 깃헙에 접근하여 푸시를 합니다. 순서는 다음과 같습니다.

  1. repo를 가져오고
  2. 새로운 트리를 만들고
  3. 커밋을 만들고
  4. 푸쉬 합니다
github.gitdata.getReference({
    owner,
    repo,
    ref: 'heads/master'
 }, (err, result) => {
    referenceCommitSha = result.data.object.sha; //sha 값을 가져와서 저장하고 
});

github.gitdata.createTree({
    owner,
    repo,
    tree: files,
    base_tree: referenceCommitSha
}, (err, result) => {
    newTreeSha = result.data.sha; // 새로운 트리를 만들고 sha 값을 얻습니다.
});

github.gitdata.createCommit({
    owner,
    repo,
    message: commitMessage,
    tree: newTreeSha,
    parents: [referenceCommitSha]
}, (err, result) => {
    newCommitSha = result.data.sha; //commit을 하고 sha 값을 얻습니다.
});

github.gitdata.updateReference({
    owner,
    repo,
    ref: 'heads/master',
    sha: newCommitSha,
    force: true
}); //푸쉬를 합니다.

모든 소스를 공개하기엔 지면 낭비인 것 같아서 대략적인 흐름만 적었습니다. 저 위의 흐름은 순차적이어야 하며 옵션과 예외처리는 따로 해야합니다.

lambda 함수 배포

위에서 작성한 프로젝트를 폴더 통채로 zip파일로 만듭니다.

그 후 .zip파일 업로드를 클릭하여 업로드를 합니다.

Inline-image-2017-11-15 22.36.29.870.png

외부 통신이 많이 들어가는 작업이라 실행시간을 3초에서 1분 30초 정도로 늘려줍니다. Inline-image-2017-11-15 22.41.14.883.png

Done~

모두 마무리 했습니다. 이제 두레이에 글을 쓰면

Inline-image-2017-11-15 22.42.30.724.png

블로그에 자동으로 등록이 됩니다. Inline-image-2017-11-15 22.43.09.525.png

처음에 생각한대로 구현이 되어서 매우 만족 스러웠습니다. 앞으로 카테고리, 태그 분류 등등 여러가지 기능을 넣어보려 합니다.

다만, 두레이는 이슈 최초 등록이 아닌 이슈 업데이트에 대한 훅이 없어서 유지보수가 어려울 수 있습니다. 또 두레이에서는 이미지 관리가 매우 편리한데, 이미지 권한 설정기능이 없어서 람다에서 두레이 이미지에 대한 권한을 얻기 위해 우회를 해야 하였습니다. (이 포스트에 자세한 내용은 쓰지 않았습니다)

관련 문서 더보기 javascript
blog comments powered by Disqus