From fee4227b6ed23a1253a115039840b731edfbd696 Mon Sep 17 00:00:00 2001 From: jun Date: Tue, 15 Oct 2024 01:14:37 +0900 Subject: [PATCH] =?UTF-8?q?feat(workflow):=20workflow=20script=20=EC=B6=94?= =?UTF-8?q?=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- appspec.yml | 8 ++-- build.gradle | 2 + docker-compose.yaml | 5 +-- scripts/build_new_deployment.sh | 14 +++++++ scripts/cleaning_old_image.sh | 3 ++ scripts/preparing_new_deployment.sh | 3 ++ scripts/start_application.sh | 40 +++++++++++++++++++ scripts/validate_service.sh | 32 +++++++++++++++ .../global/config/SecurityConfig.java | 3 +- 9 files changed, 102 insertions(+), 8 deletions(-) create mode 100644 scripts/build_new_deployment.sh create mode 100644 scripts/cleaning_old_image.sh create mode 100644 scripts/preparing_new_deployment.sh create mode 100644 scripts/start_application.sh create mode 100644 scripts/validate_service.sh diff --git a/appspec.yml b/appspec.yml index d467194..a24a27b 100644 --- a/appspec.yml +++ b/appspec.yml @@ -2,7 +2,7 @@ version: 0.0 os: linux files: - - source: / + - source: / destination: /home/ubuntu/develop/backend/build/libs overwrite: yes @@ -16,15 +16,15 @@ permissions: hooks: ApplicationStop: - - location: scripts/stop_application.sh + - location: scripts/cleaning_old_image.sh timeout: 300 runas: ubuntu BeforeInstall: - - location: scripts/before_install.sh + - location: scripts/preparing_new_deployment.sh timeout: 300 runas: ubuntu AfterInstall: - - location: scripts/after_install.sh + - location: scripts/build_new_deployment.sh timeout: 300 runas: ubuntu ApplicationStart: diff --git a/build.gradle b/build.gradle index 0fb62b3..9658250 100644 --- a/build.gradle +++ b/build.gradle @@ -68,6 +68,8 @@ dependencies { implementation 'com.google.firebase:firebase-admin:9.3.0' implementation 'com.fasterxml.jackson.core:jackson-core:2.18.0' + implementation 'org.springframework.boot:spring-boot-starter-actuator' + compileOnly 'javax.servlet:javax.servlet-api:4.0.1' implementation 'com.squareup.okhttp3:okhttp:4.10.0' diff --git a/docker-compose.yaml b/docker-compose.yaml index 4e149de..568f9eb 100644 --- a/docker-compose.yaml +++ b/docker-compose.yaml @@ -118,8 +118,6 @@ services: - campride_network - app-tier - - nginx: image: nginx:latest restart: unless-stopped @@ -132,7 +130,8 @@ services: - ./data/certbot/conf:/etc/letsencrypt - ./data/certbot/www:/var/www/certbot depends_on: - - app + - app-blue + - app-green networks: - campride_network - app-tier diff --git a/scripts/build_new_deployment.sh b/scripts/build_new_deployment.sh new file mode 100644 index 0000000..4489def --- /dev/null +++ b/scripts/build_new_deployment.sh @@ -0,0 +1,14 @@ +echo "Building new version deployment" +cd /home/ubuntu/develop/backend +cp -R /home/ubuntu/develop/backend/build/libs/* build/libs_new/ + +# 현재 실행 중인 컨테이너 확인 +CURRENT_CONTAINER=$(docker ps --filter "name=campride-api-server" --format "{{.Names}}") +if [ "$CURRENT_CONTAINER" == "campride-api-server-blue" ]; then + NEW_CONTAINER="campride-api-server-green" +else + NEW_CONTAINER="campride-api-server-blue" +fi + +# 새 버전의 이미지 빌드 +docker-compose build $NEW_CONTAINER \ No newline at end of file diff --git a/scripts/cleaning_old_image.sh b/scripts/cleaning_old_image.sh new file mode 100644 index 0000000..22f2831 --- /dev/null +++ b/scripts/cleaning_old_image.sh @@ -0,0 +1,3 @@ +echo "Cleaning up old deployment artifacts" +cd /home/ubuntu/develop/backend +docker image prune -af \ No newline at end of file diff --git a/scripts/preparing_new_deployment.sh b/scripts/preparing_new_deployment.sh new file mode 100644 index 0000000..668f112 --- /dev/null +++ b/scripts/preparing_new_deployment.sh @@ -0,0 +1,3 @@ +echo "Preparing for new deployment" +cd /home/ubuntu/develop/backend +mkdir -p build/libs_new diff --git a/scripts/start_application.sh b/scripts/start_application.sh new file mode 100644 index 0000000..4db7c3a --- /dev/null +++ b/scripts/start_application.sh @@ -0,0 +1,40 @@ +echo "Starting new version" +cd /home/ubuntu/develop/backend + +# 현재 실행 중인 컨테이너 확인 +CURRENT_CONTAINER=$(docker ps --filter "name=campride-api-server" --format "{{.Names}}") +if [ "$CURRENT_CONTAINER" == "campride-api-server-blue" ]; then + NEW_CONTAINER="campride-api-server-green" + NEW_PORT=8081 + CURRENT_PORT=8080 +else + NEW_CONTAINER="campride-api-server-blue" + NEW_PORT=8080 + CURRENT_PORT=8081 +fi + +# 새 컨테이너 시작 +docker-compose up -d $NEW_CONTAINER + +# 새 컨테이너가 준비될 때까지 대기 +echo "Waiting for the new container to be ready..." +for i in {1..30}; do + if curl -s http://localhost:$NEW_PORT/actuator/health | grep -q "UP"; then + echo "New container is ready" + break + fi + if [ $i -eq 30 ]; then + echo "New container failed to start" + exit 1 + fi + sleep 10 +done + +# Nginx 설정 업데이트 +NGINX_CONF="/home/ubuntu/develop/backend/data/nginx/nginx.conf" +sed -i "s/proxy_pass http:\/\/$CURRENT_CONTAINER:$CURRENT_PORT/proxy_pass http:\/\/$NEW_CONTAINER:$NEW_PORT/" $NGINX_CONF + +# Nginx 설정 리로드 +docker-compose exec -T nginx nginx -s reload + +echo "Switched traffic to $NEW_CONTAINER on port $NEW_PORT" \ No newline at end of file diff --git a/scripts/validate_service.sh b/scripts/validate_service.sh new file mode 100644 index 0000000..75dfe76 --- /dev/null +++ b/scripts/validate_service.sh @@ -0,0 +1,32 @@ +echo "Validating new deployment" +cd /home/ubuntu/develop/backend + +# 현재 활성 컨테이너 확인 +NEW_CONTAINER=$(docker ps --filter "name=campride-api-server" --format "{{.Names}}") +OLD_CONTAINER=$(docker ps -a --filter "name=campride-api-server" --filter "status=exited" --format "{{.Names}}") + +# 새 버전 상태 확인 +for i in {1..5}; do + response=$(curl -sS http://localhost:8080/actuator/health) + if [[ $response == *"UP"* ]]; then + echo "New version is healthy" + # 새 버전의 라이브러리를 메인 디렉토리로 이동 + mv build/libs build/libs_old + mv build/libs_new build/libs + # 이전 버전 컨테이너 중지 + docker-compose stop $OLD_CONTAINER + exit 0 + fi + sleep 10 +done + +echo "New version is not healthy. Rolling back." + +# 롤백 +NGINX_CONF="/home/ubuntu/develop/backend/data/nginx/nginx.conf" +sed -i "s/proxy_pass http:\/\/$NEW_CONTAINER:8080/proxy_pass http:\/\/$OLD_CONTAINER:8080/" $NGINX_CONF +docker-compose exec -T nginx nginx -s reload +docker-compose stop $NEW_CONTAINER +docker-compose start $OLD_CONTAINER +echo "Rolled back to $OLD_CONTAINER" +exit 1 \ No newline at end of file diff --git a/src/main/java/com/richjun/campride/global/config/SecurityConfig.java b/src/main/java/com/richjun/campride/global/config/SecurityConfig.java index 8f905b9..f662596 100644 --- a/src/main/java/com/richjun/campride/global/config/SecurityConfig.java +++ b/src/main/java/com/richjun/campride/global/config/SecurityConfig.java @@ -57,7 +57,8 @@ CorsConfigurationSource corsConfigurationSource() { @Bean public WebSecurityCustomizer webSecurityCustomizer() { return (web) -> web.ignoring() - .requestMatchers("/api/v1/token/refreshtoken", "/api/v1/login**", "/ws/**", "/wss/**", "https://fcm.googleapis.com/v1/projects/campride-87f0d/messages:send"); + .requestMatchers("/api/v1/token/refreshtoken", "/api/v1/login**", "/ws/**", "/wss/**", + "https://fcm.googleapis.com/v1/projects/campride-87f0d/messages:send", "/actuator/health"); } @Bean