전체 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
1주일간 Docker Container로 자동 배포 구성을 수행했습니다.
Nginx(Web Server)도 없고 DB도 연결하지 않고, 정말 심플하게 어플리케이션 배포하는 과정만 했는데도
이틀 정도는 하루 10시간씩 투자를 했습니다. 개인 테스트 환경에서 이 정도까지 해봤다는 것도 경험일 수 있지만, 아래와 같은 문제점이 있다는 생각이 들었습니다.
문제점
- 직접 도메인 발급하지 않았기 때문에(ngrok, 무료 기능) 매번 webhook 도메인 연결 주소를 수정해야 함
- 어플리케이션 배포시 재실행하는 과정에서 발생하는 서비스 끊김 현상
- 온프레미스 방식으로 직접 서버 설정 셋팅
- docker 실행 명령 공유 등등
유료로 도메인 고정 시키거나, 배포 전략 취하거나, Dockerfile image 생성한다거나
해결 방안에 대해서는 몇가지 알고 있지만 역시나 한번에 하기란 쉽지가 않다는 것을 느낍니다
앞으로 해보고 싶고, 해야 할 건 많지만 느리더라도 천천히 하나씩 자기 것으로 만들고 포스팅할 수 있도록 하여
좋은 영향력을 주고 받는 개발자로서 성장해야겠다는 생각이 드는 한주가 였습니다.
- "찬양합니다. SI 탈출 성공 신화 [기억보단 기록을]"
참고
기억보단 기록을 https://jojoldu.tistory.com/263
https://hudi.blog/zero-downtime-deployment-with-jenkins-and-nginx/
https://dallog.github.io/continuous-deploy-with-jenkins-1-backend/
'공부 > DevOps' 카테고리의 다른 글
Jenkins 빌드 배포시 Slack 알림 설정 (5) (0) | 2023.07.16 |
---|---|
[Ubuntu] /bin/bash로 기본 shell 변경하기 (0) | 2023.07.15 |
[Docker] Container SSH key 접속, scp 명령어로 파일 전송 (3) (0) | 2023.07.15 |
[Docker] Container IP 확인 및 SSH 접속하기 (2) (0) | 2023.07.14 |
[Docker] Jenkins 설치 및 Github 연동 (1) (0) | 2023.07.08 |
포스팅이 좋았다면 "좋아요❤️" 또는 "구독👍🏻" 해주세요!