일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | |||||
3 | 4 | 5 | 6 | 7 | 8 | 9 |
10 | 11 | 12 | 13 | 14 | 15 | 16 |
17 | 18 | 19 | 20 | 21 | 22 | 23 |
24 | 25 | 26 | 27 | 28 | 29 | 30 |
- javascript
- AWS
- php
- jsp
- jenkins
- springboot
- Spring Batch
- tool
- elasticsearch
- Git
- IntelliJ
- redis
- devops
- Design Patterns
- 요리
- Web Server
- laravel
- Oracle
- Spring
- Gradle
- it
- JVM
- db
- java
- ubuntu
- ReactJS
- 맛집
- MySQL
- linux
- Spring Boot
- Today
- Total
아무거나
[springboot] gradle 개발환경별 버저닝 빌드&배포 본문
[springboot gradle 개발환경별 버저닝 빌드&배포]
개발환경 기준 : dev, stage, master(=live)
사용툴 : jenkins + s3 + codedeploy
[빌드]
1. build.gradle에 저장될 jar이름 설정(안하면 jenkins item이름으로 기본정의됨)
jar {
archivesBaseName = "test"
}
2. build 부분에서 Add build step -> Invoke Gradle script 선택
3. jekins item 설정에서 Build 부분에서 Use Gradle Wrapper 버튼 클릭하고 설정
- Make gradlew executable 체크
- Wrapper location: ${workspace} // ${workspace}는 해당 item 경로
- Tasks: clean build
4. 빌드하고 해당 프로젝트 경로에 /build/libs 를 확인해보면 jar파일이 생성되어있다.
5. jenkins쪽 build시 실행될 script파일을 생성하자.
[springboot_build.sh]
#!/bin/bash
if [ "$#" -ne 3 ];
then
echo "Bad Not Request Parameters"
else
# parameters check
if [ $2 = "dev" -o $2 = "stage" -o $2 = "master" ];
then
# aws define
jenkinsDir="/var/lib/jenkins/workspace"
jenkinsProjectDir="$jenkinsDir/$1"
jenkinsBuildDir="$jenkinsProjectDir/build/libs"
# s3 define
s3Buckets="s3://ws.bucket/$3"
s3Region="ap-northeast-2"
# bucket object check
s3BucketObj=$(aws s3 ls $s3Buckets/)
s3BucketObjLen=${#s3BucketObj}
if [ $s3BucketObjLen -gt 0 ];
then
buildFileName=$(cd $jenkinsBuildDir/ && ls -td1 *.jar)
echo "Output Build File Name"
echo $buildFileName
if [ -f $jenkinsBuildDir/$buildFileName ]
then
if [ $2 = "master" ];
then
echo "-------------------- MASTER -------------------"
current_version="0.0.0"
before_version="0.0.0"
# version file check
if [ -f "$jenkinsProjectDir/current_version.txt" ]
then
before_version=$(cat $jenkinsProjectDir/current_version.txt)
echo "current version : $before_version"
if [ $before_version = "9.9.9" ]; then
echo "---------------------------ERROR-----------------------------"
echo "-----------------------version full.........................."
echo "---------------------------ERROR-----------------------------"
exit
fi
else
echo "0.0.0" > $jenkinsProjectDir/current_version.txt
fi
aws s3 cp $s3Buckets/$3_$2_$current_version.tar.gz $jenkinsProjectDir/$3_$2_$current_version.tar.gz --region $s3Region
aws s3 cp $s3Buckets/$3_$2_$before_version.tar.gz $jenkinsProjectDir/$3_$2_$before_version.tar.gz --region $s3Region
# versioning
if [ -f "$jenkinsProjectDir/$3_$2_0.0.0.tar.gz" ];
then
vn=$(cd $jenkinsProjectDir/ && ls -td1 *.gz | head -n 1)
vc=$(echo $vn | cut -f 5 -d '_')
vMajor=$(echo $vc | awk '{ split($0, vArr, "."); print vArr[1] }')
vMinor=$(echo $vc | awk '{ split($0, vArr, "."); print vArr[2] }')
vPatch=$(echo $vc | awk '{ split($0, vArr, "."); print vArr[3] }')
# version terms
# patch
if [ $vPatch -ge 9 ]
then
vPatch=0
vMinor=$(($vMinor+1))
else
vPatch=$(($vPatch+1))
fi
# minor
if [ $vMinor -ge 9 ]
then
vMinor=0
vMajor=$(($vMajor+1))
fi
# major
if [ $vMajor -ge 9 ]; then
echo "Major Version Max Error"
fi
current_version=$vMajor.$vMinor.$vPatch
rm -r $jenkinsProjectDir/current_version.txt
echo $current_version > $jenkinsProjectDir/current_version.txt
rm -r $jenkinsProjectDir/$3_$2_0.0.0.tar.gz
rm -r $jenkinsProjectDir/$3_$2_$before_version.tar.gz
fi
cd $jenkinsProjectDir && tar -zcvf $jenkinsProjectDir/$3_$2_latest.tar.gz .
cd $jenkinsProjectDir && tar -zcvf $jenkinsProjectDir/$3_$2_$current_version.tar.gz .
aws s3 cp $jenkinsProjectDir/$3_$2_latest.tar.gz $s3Buckets/ --region $s3Region
aws s3 cp $jenkinsProjectDir/$3_$2_$current_version.tar.gz $s3Buckets/ --region $s3Region
rm -r $jenkinsProjectDir/$3_$2_latest.tar.gz
rm -r $jenkinsProjectDir/$3_$2_$current_version.tar.gz
else
echo "--------------------DEV, STAGE-----------------"
version="0.0.0"
cd $jenkinsProjectDir && tar -zcvf $jenkinsProjectDir/$3_$2_$version.tar.gz .
aws s3 cp $jenkinsProjectDir/$3_$2_$version.tar.gz $s3Buckets/ --region $s3Region
rm -r $jenkinsProjectDir/$3_$2_$version.tar.gz
fi
else
echo "ERROR : Jar File Empty!!!!!"
fi
else
echo "S3Bucket Object empty!!!"
fi
else
echo "Bad Not Request Parameters( value = dev, stage, master )"
fi
echo "$2 build finish !! [jenkins item : $1 , version : $current_version ] "
fi
6. jenkins 빌드 아이템 설정에서 build의 순서를 지켜야된다
- Execute shell(gradle build) -> Invoke Gradle script(gradle jar 생성) -> Execute shell(빌드 스크립트 + s3업로드)
---------------------------------------- 여기까지 빌드이다. -------------------------------------------------------
[배포]
1. 최상위 루트에 appspec.yml 추가 및 스크립트 폴더 추가 (codedeploy가 읽음)
[appspec.yml]
version: 0.0
os: linux
files:
- source: /
destination: /app/api/build/
hooks:
AfterInstall:
- location: scripts/execute-deploy.sh
timeout: 180
* 최상위 루트에 실행할 스크립트를 모아둘 폴더 생성 scripts/execute-deploy.sh
[execute-deploy.sh]
#!/bin/bash
/home/ubuntu/app/api/deploy.sh > /dev/null 2> /dev/null < /dev/null &
2. 배포될 폴더 생성
- mkdir /app
- mkdir /app/api
- mkdir /app/api/build
- mkdir /app/api/jar
- sudo chown -R ubuntu:ubuntu app
[deploy.sh]
#!/bin/bash
REPOSITORY=/home/ubuntu/app/api
echo "> 현재 구동중인 애플리케이션 pid 확인"
CURRENT_PID=$(pgrep -f ws_internal_api)
echo "$CURRENT_PID"
if [ -z $CURRENT_PID ]; then
echo "> 현재 구동중인 애플리케이션이 없으므로 종료하지 않습니다."
else
echo "> kill -15 $CURRENT_PID"
kill -15 $CURRENT_PID
sleep 5
fi
echo "> 새 어플리케이션 배포"
echo "> Build 파일 복사"
cp $REPOSITORY/build/build/libs/*.jar $REPOSITORY/jar/
JAR_NAME=$(ls $REPOSITORY/jar/ |grep 'ws_internal_api' | tail -n 1)
echo "> JAR Name: $JAR_NAME"
nohup java -jar -Dspring.profiles.active=dev $REPOSITORY/jar/$JAR_NAME &
(1) CURRENT_PID=$(pgrep -f ws_internal_api)
- 기존에 수행중이던 스프링부트 어플리케이션을 종료합니다.
- pgrep은 process id만 추출하는 명령어입니다.
- -f 옵션은 프로세스 이름으로 찾습니다.
- 좀 더 자세한 옵션을 알고 싶으시면 공식 홈페이지를 참고하시면 좋습니다.
(2) if ~ else ~ fi
- 현재 구동중인 프로세스가 있는지 없는지 여부를 판단해서 기능을 수행합니다.
- process id값을 보고 프로세스가 있으면 해당 프로세스를 종료합니다.
(3) JAR_NAME=$(ls $REPOSITORY/ | grep 'ws_internal_api' | tail -n 1)
- 새로 실행할 jar 파일명을 찾습니다.
- 여러 jar파일이 생기기 때문에 tail -n로 가장 나중의 jar파일(최신 파일)을 변수에 저장합니다.
(4) nohup java -jar $REPOSITORY/$JAR_NAME &
- 찾은 jar파일명으로 해당 jar파일을 nohup으로 실행시킵니다.
- 스프링부트의 장점으로 특별히 외장 톰캣을 설치할 필요가 없습니다.
- 내장 톰캣을 사용해서 jar 파일만 있으면 바로 웹 어플리케이션 서버가 실행할수 있습니다.
- 좀 더 자세한 스프링부트의 장점을 알고 싶으시면 이전에 작성한 SpringBoot의 깨알같은 팁을 참고하시면 좋습니다.
- 일반적으로 Java를 실행시킬때는 java -jar라는 명령어를 사용하지만, 이렇게 할 경우 사용자가 터미널 접속을 끊을 경우 어플리케이션도 같이 종료가 됩니다.
- 어플리케이션 실행자가 터미널을 종료시켜도 어플리케이션은 계속 구동될 수 있도록 nohup명령어를 사용합니다.
* nohup은 실행시킨 jar파일의 로그 내용을 nohup.out 이란 파일에 남깁니다.
- nohup java -jar /home/ubuntu/app/travis/build/build/libs/springboot_restapi-0.0.1.jar &
- tail -f /home/ubuntu/nohup.out // 잘 수행되었는지 확인.
- chmod 755 /home/ubuntu/app/travis/deploy.sh // 스크립트 실행을 위한 권한 부여
- /home/ubuntu/app/travis/deploy.sh // 스크립트 작동 확인
- ps -ef | grep springboot_restapi // 실행되어있는지 확인
'Infra > DevOps' 카테고리의 다른 글
[VirtualBox] VirtualBox 포트포워딩 방법 (0) | 2020.05.11 |
---|---|
[sentry] Sentry에 java 연동 (클라우드 기준) (2) | 2020.04.16 |
Jenkins + Docker 빌드/배포 or 개발환경 구축 (0) | 2019.06.10 |
Docker를 이용한 CI 구축 연습하기 (젠킨스, 슬랙) (0) | 2019.06.10 |
vagrant로 virtualbox 생성시 password쪽 부터 로드안되는 문제 (0) | 2019.03.26 |