Travis CI로 Express를 Docker Hub에 Push 하기
최근에 Travis를 가지고 이것저것 해보고 있습니다. 최종 목표는 Travis를 활용하여 무 중단 자동 배포
를 하는 것인데 그 전에 Travis를 통해 Docker Hub에 image를 Push하는 내용을 정리하겠습니다.
본 포스팅은 크게 3가지 section 으로 나뉩니다.
- travis에 활용할 express 셋팅
- travis 셋팅 & 자동 테스트 & email notification
- build 성공 시, Docker Hub에 Image push
Express 환경구성
본 포스팅의 목적은 travis
이기 때문에 express는 간단하게 설명합니다.
npm과 node는 이미 설치되어 있다고 가정하고 아래와 같이 express-generator를 설치 후 project를 생성합니다.
npm install -g express-generator
express myapp
cd myapp
아래와 같이 간단한 사칙연산 함수 4개를 정의한 파일을 추가합니다. 제 경우 models/calc
디렉토리를 만들고 그 내부에 calc.js 파일에 작성했습니다.
exports.plus = (a, b) => a + b;
exports.minus = (a, b) => a - b;
exports.multi = (a, b) => a * b;
exports.divisor = (a, b) => a / b;
package.json
이 위치한 최 상위 경로에서 test
폴더를 만들고 하위에 test.js를 작성합니다.
const assert = require('assert');
const calc = require('../models/calc/calc')suite('[TDD] calculator test', () => {
test('add two number test', () => {
const ret = calc.plus(1,2);
assert.equal(ret, 3);
}) test('minus two number test', () => {
const ret = calc.minus(3,2);
assert.equal(ret, 1);
}) test('multiple two number test', () => {
const ret = calc.multi(3,2);
assert.equal(ret, 6);
}) test('division two number test', () => {
const ret = calc.divisor(4, 2);
assert.equal(ret, 2);
})
})
테스트에 사용할 mocha
를 설치하고 package.json
에 아래와 같이 script
에 test를 작성합니다.
{
"name": "travis-express",
"version": "0.0.0",
"private": true,
"scripts": {
"start": "nodemon app.js",
"test": "mocha -ui tdd ./test/*.js"
},
"dependencies": {
"cookie-parser": "~1.4.4",
"debug": "~2.6.9",
"express": "~4.16.1",
"http-errors": "~1.6.3",
"jade": "~1.11.0",
"morgan": "~1.9.1"
},
"devDependencies": {
"mocha": "^8.0.1",
"nodemon": "^2.0.4"
}
}
Git Repo에 push할 때 최 상위 폴더에 package.json 파일이 존재 할 경우
, travis가 자동으로 npm test
를 실행하기 때문에 저도 script에 test를 정의해 mocha로 테스트 하도록 하였습니다.
만약 테스트 코드를 작성하기 귀찮다면 package.json의 npm test를 아래와 같이 사용해도 됩니다.
"scripts": {
"start": "nodemon app.js",
"test": "exit"
},
Travis CI
https://travis-ci.com/ 로 접속하여 github 계정으로 로그인합니다. 로그인 후, 화면 우측 상단의 프로필 화면을 클릭합니다.
Settings
버튼을 클릭하면 아래처럼 어떤 repo를 active 할지 선택하는 화면이 나옵니다.
저는 express-travis-example
repo를 active 했고 github에 접속해 해당 repo의 setting
-webhooks
부분을 보면 아래와 같이 travis 정보를 확인 할 수 있습니다.
위에서 준비한 express 소스의 최상위 경로에 .travis.yml
파일을 생성하고 아래와 같이 내용을 추가하고 git push
를 실행합니다.
language: node_js
node_js:
- lts/*
before_script:
- npm install
git push
를 수행 후 바로 Travis dashboard
에 접속하면 아래와 같이 빌드가 진행 중인 상태를 볼 수 있습니다.
이 때 started
된 부분을 클릭하면 실시간으로 진행되는 빌드 상황을 볼 수 있습니다.
.travis.yml
파일 내용 중lts/*
부분은 node의 버전을 lts 최신 버전을 의미하는데, 버전을 따로 명시하지 않으면 v0.10 버전이 깔려서 const 코드에 대한 에러가 아래처럼 발생하더군요
travis
가 정상적으로 가상 환경에서 빌드를 수행하면 결과는 아래처럼 나옵니다. 로그 중간에 npm test
를 수행하여 테스트 결과도 정상적으로 나온 것 을 알 수 있습니다.
만약 package.json
파일에 npm test가 정의되지 않을 경우
빌드 log에는 에러가 발생합니다.
다만 빌드의 최종 결과는 성공입니다. 아래와 같이 Passed
상태로 메일로 전달됩니다.
travis는 빌드에 대한 결과를 email, slack, 채팅 등 다양한 방법으로 notification
할 수 있습니다. default는 이메일
인데 위 과정을 수행 후 Github에 등록된
메일로 build 결과를 수신 할 수 있었습니다.
실제로 저는 2번 fail 후 성공했습니다. 메일 내용을 보면 Failed
, Still Failling
, Fixed
로 온 것을 볼 수 있습니다.
travis는 default로 빌드가 실패한 경우, 실패가 fix 된 경우
에만 노티합니다. 만약 성공한 경우에도
노티를 받고 싶다면 .travis.yml
파일을 아래와 같이 수정하면 됩니다.
language: node_js
node_js:
- lts/*
before_script:
- npm install
notifications:
email:
on_success: always
만약 Github에 등록된 메일이 아니라 다른 메일, 혹은 다수의 메일
에 전달하고 싶다면 .travis.yml 파일에 메일 주소를 명시합니다.
language: node_js
node_js:
- lts/*
before_script:
- npm install
notifications:
email:
recipients:
- example1@example.com
- example2@example.com
Docker Hub Image Push
전체 흐름은 아래와 같습니다.
- travis와 연동 된 repo에 push 한다.
- travis에서 빌드가 성공할 경우 docker hub에 image를 push한다.
우선 Docker Hub에 image를 올리려면 계정 정보가 필요합니다. .travis.yml
파일에 DOCKER_USER
정보를 기술합니다.
.
.
env:
global:
- DOCKER_USER=DOCKER_ID
패스워드를 평문으로 작성할 순 없으므로 암호화하여 추가 할 수 있도록 travis gem을 설치합니다. 우선 Windows 에서 Ruby를 설치합니다. 설치 후 아래 명령어로 travis gem을 설치합니다.
gem install travis
설치 후 encrypt 명령어로 패스워드를 암호화합니다.
travis encrypt DOCKER_PASS="DOCKER_PASSWORD" --add
그럼 .travis.yml
파일에 암호화 된 password가 secure 속성으로 추가됩니다.
env:
global:
- DOCKER_USER=DOCKER_ID
- secure: I87q0F+5I9Kx/IH/ZMT1zQ................................
.travis.yml
파일에 어떻게 배포할지 deploy 부분을 작성합니다. travis가 docker와 관련된 provider를 제공하지 않기 때문에 저는 script를 사용했습니다.
deploy:
provider: script
script: bash docker_push.sh
Docker 계정 정보와 deploy가 반영된 최종 .travis.yml
내용입니다.
다음은 travis가 deploy하는 시점에 실행 할 docker_push.sh
파일 내용입니다.
#!/bin/bash# docker.io 로그인
echo "$DOCKER_PASS" | docker login -u "$DOCKER_USER" --password-stdin# Dockerfile 빌드
docker build -t express:0.0.1 .# local image에 tag 추가
docker tag express:0.0.1 sjk5766/express:0.0.1# docker hub에 push
docker push sjk5766/express:0.0.1
아래는 Dockerfile
내용입니다.
FROM node:12
MAINTAINER sjk5766 <wjdrnr6662@gmail.com>WORKDIR /app
COPY package*.json ./RUN npm install
COPY . .EXPOSE 3000
CMD [ "node", "app.js" ]
정리하면 travis가 빌드에 사용할 config 파일인 .travis.yml
, docker hub에 배포하기 위한 명령어가 작성된 docker_push.sh
, image를 생성 할Dockerfile
까지 준비되었고 Git에 commit & push 합니다.
Travis가 정상적으로 배포에 성공할 경우 Travis 로그에서 마지막은 아래와 같이 나타납니다.
Travis가 빌드 & 배포 종료 후 Docker Hub
에도 정상적으로 보입니다.
Docker Hub
에서 image를 local에 pull
받은 후 run
시켰을 때도 정상적으로 작동합니다.
결국 Travis를 활용하여 Docker Hub에 image는 배포했지만 실제로 운영하는 서버에 배포하기 위해선 수동적인 작업
or 자동 배포를 위한 추가적인 작업
들이 필요하겠네요.