Last active
March 1, 2024 15:58
-
-
Save hyeon0208/5a68041ffc4dd1f4969a80a6f5239b65 to your computer and use it in GitHub Desktop.
무중단 배포
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
# CodeDeploy 버전 (테스트 모드 : 0.0 ) | |
version: 0.0 | |
# 배포할 서버의 운영체제 | |
os: linux | |
files: | |
- source: / # CodeDeploy에서 전달해 준 파일 중 destination으로 이동시킬 대상을 지정 (루트 경로 : 전체 파일) | |
destination: /home/ec2-user/app/deploy/zip/ # source에서 지정된 파일을 받을 위치 | |
overwrite: yes # 기존 파일들을 덮어 쓰기 | |
# CodeDeploy에서 EC2로 넘겨준 파일들을 모두 ec2-user 권한 부여. | |
permissions: | |
- object: / | |
pattern: "**" | |
owner: ec2-user | |
group: ec2-user | |
# CodeDeploy 배포 단계에서 실행할 명령어를 지정. (차례 대로 스크립트들이 실행 ) | |
hooks: | |
AfterInstall: | |
- location: stop.sh # 엔진엑스와 연결되어 있지 않은 스프링 부트를 종료. | |
timeout: 60 | |
runas: ec2-user | |
ApplicationStart: | |
- location: start.sh # Nginx와 연결되어 있지 않은 Port로 새 버전의 스프링 부트 시작. | |
timeout: 60 | |
runas: ec2-user | |
ValidateService: | |
- location: health.sh # 새 스프링 부트가 정상적으로 실행됬는지 확인. | |
timeout: 60 | |
runas: ec2-user |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
name: deploy to ec2 | |
on: | |
push: | |
branches: [ "master" ] | |
jobs: | |
deploy: | |
runs-on: ubuntu-latest | |
steps: | |
- name: Checkout | |
uses: actions/checkout@v3 | |
- name: Set up JDK 11 | |
uses: actions/setup-java@v3 | |
with: | |
java-version: '11' | |
distribution: 'temurin' | |
- name: Grant execute permission for gradlew | |
run: chmod +x ./gradlew | |
- name: Build with Gradle | |
run: ./gradlew clean bootJar | |
- name: Generate deployment package | |
run: | | |
mkdir -p before-deploy | |
cp scripts/*.sh before-deploy/ | |
cp appspec.yml before-deploy/ | |
cp build/libs/*.jar before-deploy/ | |
cd before-deploy && zip -r before-deploy * | |
cd ../ && mkdir -p deploy | |
mv before-deploy/before-deploy.zip deploy/fruit-mall.zip | |
shell: bash | |
- name: Make zip file | |
run: zip -r ./fruit-mall.zip . | |
shell: bash | |
- name: Deliver to AWS S3 | |
uses: aws-actions/configure-aws-credentials@v1 | |
with: | |
aws-access-key-id: ${{ secrets.AWS_ACCESS_KEY_ID }} | |
aws-secret-access-key: ${{ secrets.AWS_SECRET_ACCESS_KEY }} | |
aws-region: us-east-1 | |
- name: Upload to S3 | |
run: aws s3 cp ./deploy/fruit-mall.zip s3://fruit-mall-s3/jar-folder/ | |
- name: Code Deploy | |
run: | | |
aws deploy create-deployment \ | |
--application-name fruit-mall-codedeploy \ | |
--deployment-config-name CodeDeployDefault.AllAtOnce \ | |
--deployment-group-name fruit-mall-codedeploy-group \ | |
--file-exists-behavior OVERWRITE \ | |
--s3-location bucket=fruit-mall-s3,bundleType=zip,key=jar-folder/fruit-mall.zip \ | |
--region us-east-1 |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/usr/bin/env bash | |
# Nginx와 연결되지 않은 포트로 스프링 부트가 잘 수행되었는지 체크 | |
ABSPATH=$(readlink -f $0) | |
ABSDIR=$(dirname $ABSPATH) | |
source ${ABSDIR}/profile.sh | |
source ${ABSDIR}/switch.sh | |
IDLE_PORT=$(find_idle_port) | |
echo "> Health Check Start!" | |
echo "> IDLE_PORT: $IDLE_PORT" | |
echo "> curl -s http://localhost:$IDLE_PORT/profile " | |
sleep 10 | |
for RETRY_COUNT in {1..10} | |
do | |
RESPONSE=$(curl -s http://localhost:${IDLE_PORT}/profile) | |
UP_COUNT=$(echo ${RESPONSE} | grep 'real' | wc -l) | |
if [ ${UP_COUNT} -ge 1 ] | |
then # $up_count >= 1 ("real" 문자열이 있는지 검증) | |
echo "> Health check 성공" | |
switch_proxy # 잘 떳다면, switch.sh의 switch_proxy로 Nginx 프록시 설정을 변경 | |
break | |
else | |
echo "> Health check의 응답을 알 수 없거나 혹은 실행 상태가 아닙니다." | |
echo "> Health check: ${RESPONSE}" | |
fi | |
if [ ${RETRY_COUNT} -eq 10 ] | |
then | |
echo "> Health check 실패. " | |
echo "> 엔진엑스에 연결하지 않고 배포를 종료합니다." | |
exit 1 | |
fi | |
echo "> Health check 연결 실패. 재시도..." | |
sleep 10 | |
done |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/usr/bin/env bash | |
# 쉬고 있는 profile 찾기: real1이 사용중이면 real2가 쉬고 있고, 반대면 real1이 쉬고 있음 | |
function find_idle_profile() | |
{ # 현재 엔진엑스가 바라보고 있는 스프링부트가 정상적으로 수행 중인지 확인. | |
RESPONSE_CODE=$(curl -s -o /dev/null -w "%{http_code}" http://localhost/profile) | |
if [ ${RESPONSE_CODE} -ge 400 ] # 400 보다 크면 (즉, 40x/50x 에러 모두 포함) | |
then # 오류가 발생하면 real2를 현재 profile로 사용 | |
CURRENT_PROFILE=real2 | |
else | |
CURRENT_PROFILE=$(curl -s http://localhost/profile) | |
fi | |
if [ ${CURRENT_PROFILE} == real1 ] | |
then # IDLE_PROFILE 은 엔진엑스와 연결되지 않은 프로필 , 스프링 부트 프로젝트를 이 프로필로 연결 | |
IDLE_PROFILE=real2 | |
else | |
IDLE_PROFILE=real1 | |
fi | |
# bash는 return value가 안되니 *제일 마지막줄에 echo로 해서 결과 출력*후, 클라이언트에서 값을 사용한다 | |
echo "${IDLE_PROFILE}" | |
} | |
# 쉬고 있는 profile의 port 찾기 | |
function find_idle_port() | |
{ | |
IDLE_PROFILE=$(find_idle_profile) | |
if [ ${IDLE_PROFILE} == real1 ] | |
then | |
echo "8081" | |
else | |
echo "8082" | |
fi | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/usr/bin/env bash | |
# Nginx와 연결되지 않은 포트로 스프링 부트가 잘 수행되었는지 체크 | |
ABSPATH=$(readlink -f $0) | |
ABSDIR=$(dirname $ABSPATH) | |
source ${ABSDIR}/profile.sh | |
source ${ABSDIR}/switch.sh | |
IDLE_PORT=$(find_idle_port) | |
echo "> Health Check Start!" | |
echo "> IDLE_PORT: $IDLE_PORT" | |
echo "> curl -s http://localhost:$IDLE_PORT/profile " | |
sleep 10 | |
for RETRY_COUNT in {1..10} | |
do | |
RESPONSE=$(curl -s http://localhost:${IDLE_PORT}/profile) | |
UP_COUNT=$(echo ${RESPONSE} | grep 'real' | wc -l) | |
if [ ${UP_COUNT} -ge 1 ] | |
then # $up_count >= 1 ("real" 문자열이 있는지 검증) | |
echo "> Health check 성공" | |
switch_proxy # 잘 떳다면, switch.sh의 switch_proxy로 Nginx 프록시 설정을 변경 | |
break | |
else | |
echo "> Health check의 응답을 알 수 없거나 혹은 실행 상태가 아닙니다." | |
echo "> Health check: ${RESPONSE}" | |
fi | |
if [ ${RETRY_COUNT} -eq 10 ] | |
then | |
echo "> Health check 실패. " | |
echo "> 엔진엑스에 연결하지 않고 배포를 종료합니다." | |
exit 1 | |
fi | |
echo "> Health check 연결 실패. 재시도..." | |
sleep 10 | |
done |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/usr/bin/env bash | |
ABSPATH=$(readlink -f $0) # 절대경로 | |
ABSDIR=$(dirname $ABSPATH ) # 현재 stop.sh가 속해있는 경로를 찾는다. | |
source ${ABSDIR}/profile.sh # 자바로 보면 일종의 import 구문, stop.sh에서도 profile.sh의 여러 function을 사용 가능 | |
IDLE_PORT=$(find_idle_port) | |
echo "> $IDLE_PORT 에서 구동중인 애플리케이션 pid 확인" | |
IDLE_PID=$(lsof -ti tcp:${IDLE_PORT}) | |
if [ -z ${IDLE_PID} ] | |
then | |
echo "> 현재 구동중인 애플리케이션이 없으므로 종료하지 않습니다." | |
else | |
echo "> kill -15 $IDLE_PID" | |
kill -15 ${IDLE_PID} | |
sleep 5 | |
fi |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/usr/bin/env bash | |
ABSPATH=$(readlink -f $0) | |
ABSDIR=$(dirname $ABSPATH) | |
source ${ABSDIR}/profile.sh | |
function switch_proxy() { | |
IDLE_PORT=$(find_idle_port) | |
echo "> 전환할 Port: $IDLE_PORT" | |
echo "> Port 전환" | |
# 하나의 문장을 만들어 파이프라인(|)으로 넘겨 주기 위해 echo를 사용. tee 는 앞의 문장을 읽어 해당 경로의 파일에 저장. | |
echo "set \$service_url http://127.0.0.1:${IDLE_PORT};" | sudo tee /etc/nginx/conf.d/service-url.inc | |
echo "> 엔진엑스 Reload" | |
# restart와 달리 끊김 없이 다시 불러온다. (중요한 설정을 반영해야한다면 restart 사용) | |
# 여기선 외부의 설정 파일인 service-url을 다시 불러오기 때문에 reload로 가능 | |
sudo service nginx reload | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment