배포과정은 다음과 같다.
1) 로컬에서 github로 프로젝트 push
2) 로컬에서 EC2에 배포파일 전송
3) EC2에서 배포파일 실행
4) 재배포시 로컬에서 github에 프로젝트 재업로드하고 EC2에서 배포파일 실행
리눅스 SSH 접속을 위해 mobaXterm을 사용했고 ubuntu 터미널 환경에서
환경변수 파일로 사용하기위해 임의의 var.sh 파일을 생성한다.
#임의의 var.sh 환경변수 파일
#!/bin/bash
GITHUB_ID="본인의 GITHUB 아이디"
PROJECT_NAME="본인의 레파지토리 이름"
PROJECT_VERSION="0.0.1"
PROJECT_PID=""
JAR_PATH=""
export GITHUB_ID
export PROJECT_NAME
export PROJECT_PID
export JAR_PATH
이때 #!/bin/bash
는 경량스크립트인 sh를 안쓰고 bash를 쓰겠다는 의미.
PROJECT_VERSION은 build.gradle 내부의 version값을 사용.
서버가 멈춰있을때 자동으로 재시작하기 위한 임의의 check-and-restart.sh 파일을 생성한다.
#임의의 check-and-restart.sh 파일
#!/bin/bash
source ./var.sh
if [ -z "$PROJECT_PID" ]; then # 문자길이가 0이면 true 즉 서버가 멈춰있으면
nohup java -jar -Dspring.profiles.active=prod ${JAR_PATH} 1>${HOME}/log.out 2>${HOME}/err.out &
fi
임의의 실행파일인 deploy.sh 파일 생성
#임의의 deploy.sh 실행파일
#!/bin/bash
# 1. env variable(환경변수)
source ./var.sh
echo "1. env variable setting complete"
# 2. cron delete
touch crontab_delete
crontab crontab_delete
rm crontab_delete
echo "2. cron delete complete"
# 3. server checking
if [ -n "${PROJECT_PID}" ]; then # -n은 문자열길이가 0이 아니면 true
# re deploy
kill -9 $PROJECT_PID
echo "3. project kill complete"
else
# first deploy
# 3-1 apt update
sudo apt-get -y update 1>/dev/null
echo "3-1 apt-get update completee"
# 3-2 jdk install
sudo apt-get -y install openjdk-11-jdk 1>/dev/null
echo "3-2 jdk install complete"
# 3-3 timezone
sudo timedatectl set-timezone Asia/Seoul
echo "3-3 timezone setting complete"
fi
#4. project folder delete
rm -rf ${HOME}/${PROJECT_NAME}
echo "4 project folder delete complete"
#5. git clone
git clone https://github.com/${GITHUB_ID}/${PROJECT_NAME}.git
sleep 3s
echo "git clone complete"
#6. gradlew +x gradle이 실행파일이 아니여서 실행권한을 준다
chmod u+x ${HOME}/${PROJECT_NAME}/gradlew
echo "6. gradlew u+x complete"
#7. build jar파일이 만들어진다
cd ${HOME}/${PROJECT_NAME}
./gradlew build
echo "7. gradlew build complete"
#8. start jar
nohup java -jar -Dspring.profiles.active=prod ${JAR_PATH} 1>log.out 2>err.out &
echo "8. start server complted"
#9. cron registration
# register others... you use >> (append)
touch crontab_new # 빈파일인 crontab_new 를 생성하고
echo "* * * * * ${HOME}/check-and-restart.sh" 1>>crontab_new # HOME 경로에 check-and-restart.sh 라는 파일을 1분마다 실행하고나서,
# 그 결과를 만들어놓은 빈파일인 crontab_new에 추가시킨다
crontab crontab_new # 그리고 이것을 crontab에 추가시킨다.
rm crontab_new # 추가가 끝났으면 해당파일을 삭제한다.
echo "9. cron registration complete"
crontab 설정은 vim-basic이며
cron 표현식에서 별5개( * * * * * )는 실행주기를 결정하는것으로 각 순서대로 분(0-59) 시간(0-23) 일(1-31) 월(1-12) 요일(0-6) 을 의미한다.
이때 왜 sleep 3s로 딜레이를 줄까??
apt-get update 혹은 apt-get install은 동기식이라 순서대로 진행이 되지만
git clone의 경우 비동기식이라 순서대로 진행되지 않으므로 다운요청만하고 다운로드가 완료되기전에 build를 하면 문제가 되므로 일정시간 딜레이를 준다.
./deploy.sh
명령어로 실행한다음 netstat -nlpt
로 확인했을때 8080포트가 실행되고 있는것을 확인한다.
ps -ef
명령어로 PID를 확인하고
kill -9 45789 ( kill -9 PID번호
) 명령어로 강제로 삭제한다음 netstat -nlpt로 확인했을때 8080포트가 사라진것을 확인한다.
1분뒤에 다시 ps -ef 명령어로 확인헤보면 자동으로 재시작된 것을 확인 할 수 있다.
출처
- 이지업 개발자를 위한 AWS DevOps 입문 강의