리셋 되지 말자

[Jenkins] publish over SSH를 이용한 Docker 서비스 배포(4) 본문

CI CD

[Jenkins] publish over SSH를 이용한 Docker 서비스 배포(4)

kyeongjun-dev 2021. 5. 27. 13:10

이전 게시물에서는 단순히 echo hello world > helloworld.txt 커맨드를 이용해 단순히 'publish over SSH'를 이용해 build 과정이 동작하는지만 체크했다.

이제 실제로 간단한 nodejs 서비스를 Docker 컨테이너 형태로 배포해본다.

 

준비사항

nodejs 서버스가 배포될 서버에 Docker가 설치되어 있어야 한다.

 

Jenkins 빌드 과정 수정

Jenkins의 Item으로 돌아가서, '구성'을 선택

 

현재 구성 상태이다. 'Exec command'를 이제 수정한다.

 

 

여기서 설정한 Exec command를 사용하여 여러번 webhook을 날리게 되면, git clone을 받아온 상태에서 또 git clone을 받아오므로 에러가 발생하게 된다. webhook이 발생하고, Jenkins 에서 빌드할 때마다 직접 서버에 접속하여 git clone된 디렉토리를 삭제해 주어야한다.
이러한 문제는 게시글 마지막 부분에서 Exec command를 수정한다.

- Exec command

git clone https://github.com/Penguin135/my_node_practice.git &&
cd my_node_practice &&
docker build -t node:practice . &&
docker run -d -p 9999:9999 --name node node:practice node index.js

간단히 설명하자면

  1. 수정된 소스코드를 github로부터 clone (위처럼 clone을 하면, 'my_node_practice' 디렉토리가 생성됨)
  2. 'my_node_practice' 디렉토리로 이동한 뒤, 디렉토리 안에 있는 Dockerfile을 이용해 'node:practice'라는 이미지를 build
  3. 빌드된 'node:practice' 이미지를 node라는 이름의 컨테이너로 실행 (실행 시, 'node index.js' 커맨드를 컨테이너 내부에서 실행시켜서 nodejs를 실행)

호스트의 9999번 포트와 컨테이너의 9999번 포트로 포트포워딩하는 이유는 'index.js' 의 코드에서 포트를 9999로 설정했기 때문

 저장 후에, 다시 README.md를 수정하고 push를 해본다.

 

테스트 수행 결과

Github에 push를 했으므로, Jenkins의 빌드 과정이 수행되는걸 확인할 수 있다.

 

build가 성공하면 위 그림처럼 초록색 동그라미 체크(?)표시로 변한다.

 

서버로 접속해보면, nodejs 컨테이너 서비스가 잘 동작하는 것을 확인할 수 있다.

 

Jenkins 빌드 과정 수정 - 2

위에서 언급한 git clone 관련 문제나 컨테이너 실행 관련 문제를 고려하여 Exec command를 수정해본다.

- Exec command

rm -rf my_node_practice &&
git clone https://github.com/Penguin135/my_node_practice.git &&
cd my_node_practice &&
docker build -t node:practice . &&
sh container_check.sh

기존의 Exec command에서 서버에 있는 git 디렉토리를 먼저 제거한 후, git clone을 수행함으로써 에러를 방지한다.
build를 성공하면, 'container_check.sh'라는 스크립트를 실행하는데 내용은 아래와 같다.

 

#/bin/sh

NODE_CONTAINER_ID=`docker ps -aq --filter 'name=node'`

if [ -n "$NODE_CONTAINER_ID" ];
  then
    echo "node container exist"
    docker stop $NODE_CONTAINER_ID
    docker rm $NODE_CONTAINER_ID
    docker run -d -p 9999:9999 --name node node:practice node index.js
  else
    echo "node container not exist"
    docker run -d -p 9999:9999 --name node node:practice node index.js
fi

'node'라는 이름의 컨테이너가 이미 실행 중이거나 중지 상태이면 컨테이너를 중지 및 제거하고, 다시 컨테이너를 실행한다

'node'라는 이름의 컨테이너가 실행중이 아니라면, 그냥 컨테이너를 실행한다.

 

nodejs 서비스 수정

Jenkins 빌드 과정을 전부 수정했다면 이제 실제로 nodejs 서비스에 사용되는 index.js 를 수정하고, 변경 사항이 제대로 nodejs 서버에 적용 되는지 확인해본다.

- 기존 index.js 코드

const express = require('express')
const app = express()
const port = 9999

app.get('/', (req, res) => {
  res.send('Welcome')
})

app.get('/api', (req, res)=>{
    res.send('This is API page')
})

app.listen(port, () => {
  console.log(`Example app listening at http://localhost:${port}`)
})

 

- 변경한 index.js 코드

const express = require('express')
const app = express()
const port = 9999

app.get('/', (req, res) => {
  res.send('Welcome')
})

app.get('/api', (req, res)=>{
    res.send('This is API page')
})

app.get('/users', (req, res)=>{
  res.send('This is users page')
})

app.listen(port, () => {
  console.log(`Example app listening at http://localhost:${port}`)
})

변경 전에는 '/'랑 '/api' 경로에 대한 response만 있었는데, '/users' 경로로 접속했을 때, 'This is users page'가 표시되면 성공이다.

 

Github에 push한 이후에, nodejs 서버에 반영이 잘 되는 것을 확인

 

마무리

pubish over SSH를 사용해서 직접 shell 명령을 이용해 서버에 배포하는 방식은 매우 간단한 방법이다. 그와 동시에 여기서 구현한 Docker 서비스 배포는 매우 간단하다. Test 과정도 없고, Image 레지스트리도 없다.
또한, 모든 Github branch에서 push가 일어나면, 무조건 main 브랜치의 내용을 가져와서 서버에 배포한다. 이런 경우는 현업에서 거의 없다.
기초를 통해서 점점 발전시켜 나갈 수 있기를...

Comments