공부/DevOps

[Docker] Jenkins Build, Deploy, Execute Shell / 자동배포 환경 테스트 (4)

leejinwoo1126 2023. 7. 15. 21:01
반응형

 

 

 


전체 flow 

해당 포스팅에서는 *.war 빌드 배포 후 hello world 화면 확인하는 과정만을 기록

 

Jenkins Execute Shell 작성  

 

1. Execute Shell 

#!/bin/bash
./gradlew clean bootWar

 

2. Execute Shell 

#!/bin/bash 
BUILD_FILE=$(find . -name *.war)
FILE_NAME=`basename $BUILD_FILE`

HOST=ubuntu1
USER=ubuntu
LOC=/home/ubuntu/project/wars
SYMBOLIC_LINK=/home/ubuntu/project/dev.war
RUN_CMD=/home/ubuntu/project/deploy.sh

echo "> copy ${BUILD_FILE} to ${HOST}:{$LOC}/"
scp $BUILD_FILE $USER@$HOST:$LOC/

echo "> change symbolic link ${SYMBOLIC_LINK} -> ${LOC}/${FILE_NAME} "
ssh $USER@$HOST ln -sf $LOC/$FILE_NAME $SYMBOLIC_LINK

echo "> run deploy.sh"
ssh $USER@$HOST $RUN_CMD

요약 설명

- BUILD_FILE : 현재 item의 workspace(/var/jenkins_home/workspace/<아이템명>/) 기준으로 *.war 찾음 

- FILE_NAME : 파일 경로를 제외한 파일명만 뽑음. 예) dev-0.0.2.war

- HOST ~ RUN_CMD의 경우 배포할 ubuntu1 container 정보 파라미터

- scp $BUILD_FILE $USER@$HOST:$LOC/   : war 파일을 host container 경로로 업로드 

- ssh $USER@$HOST ln -sf $LOC/$FILE_NAME $SYMBOLIC_LINK : 새로 업로드한 파일에 대해 심볼릭 링크 생성 (-f : force)

- ssh $USER@$HOST $RUN_CMD : host container에 미리 작성해둔 deploy.sh 실행

 

현업에서 보통 root 계정으로  application을 실행하진 않고, 임의 계정을 생성하여 보통 작업 합니다. 
- ubuntu1 container에 ubuntu 계정으로 dev-*.war 배포 및 실행

 

Directory 생성

# ubuntu1 컨테이너 접속
$ docker exec -it ubuntu1 /bin/bash 

# 배포용 디렉토리 생성
$ cd /home/ubuntu
$ mkdir project 

# 폴더 소유주 변경
$ chown ubuntu:ubuntu project

# build 배포시 wars 폴더에 업로드
$ mkdir /home/ubuntu/project/wars

 

 

deploy.sh 

host container(ubuntu1)에 shell script 작성 

$ cd /home/ubuntu/project
$ vim deploy.sh

 

구동 중인 어플리케이션 PID를 찾아 종료하고, 어플리케이션을 실행

#!/bin/bash 

WAR_NAME=dev.war

echo "> PID 확인"
#CURRENT_PID=$(ps -ef | grep $WAR_NAME | grep java | awk '{print $2}')
CURRENT_PID=$(pgrep -f $WAR_NAME)

echo "$CURRENT_PID"

if [ -z $CURRENT_PID ]; then
   echo "> 현재 구동중인 어플리케이션이 없으므로 종료하지 않습니다"
else
   echo "> kill -15 $CURRENT_PID"
   kill -15 $CURRENT_PID
   sleep 10
fi

echo "> 어플리케이션 실행 "

nohup java -jar /home/ubuntu/project/$WAR_NAME > /dev/null 2>&1 &

- pgrep 을 오늘 처음 알았다는 사실에 충격 .. (pgrep = ps + grep)

 

권한 수정

$ chmod 755 deploy.sh

배포 및 어플리케이션 접속

- build.gradle에 version 수정 후 git push 를 하거나 jenkins item에서 바로 빌드 수행

 

정상적으로 접속 확인

 

 

Trouble Shooting 

문제) Jenkins 배포시 deploy.sh 실행 종료되지 않아 무한 로딩 발생 

해결) *.war 실행 명령어에서 redirect 처리 하여 해결 

# deploy.sh 최하단
nohup java -jar /home/ubuntu/project/$WAR_NAME > /dev/null 2>&1 &

 

https://goateedev.tistory.com/48

 

원격 shell 실행 시, job이 끝나지 않는 현상

jenkins 에서 nohup으로 background 프로세스 수행시, 위와 같이 job이 끝나지 않는 경우가 있다. SSH를 통해 스크립트를 수행시, 표준 출력이 닫히거나 timeout이 발생할 때 까지 스크립트가 계속해서 열려

goateedev.tistory.com

 


1주일간 Docker Container로 자동 배포 구성을 수행했습니다. 

 

Nginx(Web Server)도 없고 DB도 연결하지 않고, 정말 심플하게 어플리케이션 배포하는 과정만 했는데도

이틀 정도는 하루 10시간씩 투자를 했습니다. 개인 테스트 환경에서 이 정도까지 해봤다는 것도 경험일 수 있지만, 아래와 같은 문제점이 있다는 생각이 들었습니다.

 

문제점

- 직접 도메인 발급하지 않았기 때문에(ngrok, 무료 기능) 매번 webhook 도메인 연결 주소를 수정해야 함

- 어플리케이션 배포시 재실행하는 과정에서 발생하는 서비스 끊김 현상

- 온프레미스 방식으로 직접 서버 설정 셋팅 

- docker 실행 명령 공유 등등

 

유료로 도메인 고정 시키거나, 배포 전략 취하거나, Dockerfile image 생성한다거나 
해결 방안에 대해서는 몇가지 알고 있지만 역시나 한번에 하기란 쉽지가 않다는 것을 느낍니다

 

앞으로 해보고 싶고, 해야 할 건 많지만 느리더라도 천천히 하나씩 자기 것으로 만들고 포스팅할 수 있도록 하여

좋은 영향력을 주고 받는 개발자로서 성장해야겠다는 생각이 드는 한주가 였습니다.

 

- "찬양합니다. SI 탈출 성공 신화 [기억보단 기록을]"


참고

기억보단 기록을 https://jojoldu.tistory.com/263

 

5) 스프링부트로 웹 서비스 출시하기 - 5. EC2에 배포하기

이번 시간엔 지금까지 개발한 내용을 EC2에 배포 해보겠습니다. (모든 코드는 Github에 있습니다.) 5-1. EC2에 Git 설치 및 프로젝트 Clone 배포에 앞서 기반작업이 되는 Java와 Git을 EC2에 설치하겠습니다

jojoldu.tistory.com

https://hudi.blog/zero-downtime-deployment-with-jenkins-and-nginx/

 

Jenkins와 Nginx로 스프링부트 애플리케이션 무중단 배포하기

무중단 배포가 왜 필요할까? 카카오톡 서버가 새로운 버전이 배포될 때 마다 카톡을 일시적으로 사용할 수 없다면 누가 카카오톡을 사용할까? 더군다나 지금처럼 애자일하게 자주 배포하는 환

hudi.blog

https://dallog.github.io/continuous-deploy-with-jenkins-1-backend/

 

젠킨스를 사용한 달록팀의 지속적 배포 환경 구축기 (1) - 백엔드편

이 글은 우테코 달록팀 크루 후디가 작성했습니다. 안녕하세요, 달록팀 후디입니다. 지난번 포스팅에서 달록팀이 도커를 활용하여 EC2 인스턴스에 도커를 설치한 과정을 이야기 드렸었죠. 이번

dallog.github.io

 

반응형