From c511a052ffdf78b6541c846aa2ee90681de479fd Mon Sep 17 00:00:00 2001 From: Jinseong01 <147074506+Jinseong01@users.noreply.github.com> Date: Wed, 12 Nov 2025 01:47:15 +0900 Subject: [PATCH 01/14] =?UTF-8?q?chore:=20=EC=84=9C=EB=B8=8C=EB=AA=A8?= =?UTF-8?q?=EB=93=88=20=EC=84=A4=EC=A0=95=20=EB=B0=8F=20=EB=A1=9C=EC=BB=AC?= =?UTF-8?q?=20=EA=B0=9C=EB=B0=9C=20=ED=99=98=EA=B2=BD=20=EC=84=B8=ED=8C=85?= =?UTF-8?q?=20(#2)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - config를 서브모듈로 등록 - 빌드 시 config의 파일을 resources로 복사 - 로컬 개발용 docker-compose.yml 작성 --- .gitignore | 6 ++++ .gitmodules | 3 ++ README.md | 2 +- build.gradle | 8 +++++ config | 1 + docker-compose.yml | 34 +++++++++++++++++++ .../study/base/DevopsBaseApplication.java | 1 - src/main/resources/application.properties | 1 - 8 files changed, 53 insertions(+), 3 deletions(-) create mode 100644 .gitmodules create mode 160000 config create mode 100644 docker-compose.yml delete mode 100644 src/main/resources/application.properties diff --git a/.gitignore b/.gitignore index 2c18924..335e579 100644 --- a/.gitignore +++ b/.gitignore @@ -35,3 +35,9 @@ out/ ### VS Code ### .vscode/ + +# 설정 파일 +src/main/resources/*.properties + +# Docker 로컬 볼륨 데이터 +db/ \ No newline at end of file diff --git a/.gitmodules b/.gitmodules new file mode 100644 index 0000000..693d933 --- /dev/null +++ b/.gitmodules @@ -0,0 +1,3 @@ +[submodule "config"] + path = config + url = https://github.com/JS-DevOps-Study/docker-compose-deploy-config.git diff --git a/README.md b/README.md index 81044dc..3727f8a 100644 --- a/README.md +++ b/README.md @@ -16,7 +16,7 @@ Spring Boot 기반 프로젝트 템플릿 - 형식: `타입/ISSUE번호-설명` - 타입: feature, bugfix, refactor, chore, test, hotfix, docs - ex) - - feature/#114-auth-login + - feature/114-auth-login - release/v1.2.0 (예외) --- diff --git a/build.gradle b/build.gradle index 6d703f1..1c8660f 100644 --- a/build.gradle +++ b/build.gradle @@ -29,6 +29,7 @@ dependencies { implementation 'org.springframework.boot:spring-boot-starter-web' implementation 'org.springframework.boot:spring-boot-starter-data-jpa' implementation 'org.springframework.boot:spring-boot-starter-validation' + implementation 'org.springframework.boot:spring-boot-starter-actuator' // Spring Security // implementation 'org.springframework.boot:spring-boot-starter-security' @@ -53,3 +54,10 @@ dependencies { tasks.named('test') { useJUnitPlatform() } + +processResources.dependsOn('copyPrivateProperties') +tasks.register("copyPrivateProperties", Copy) { + from './config' + include "*.properties" + into 'src/main/resources' +} \ No newline at end of file diff --git a/config b/config new file mode 160000 index 0000000..dc7003d --- /dev/null +++ b/config @@ -0,0 +1 @@ +Subproject commit dc7003d19dd6730ee415f50778e8c57379fcac91 diff --git a/docker-compose.yml b/docker-compose.yml new file mode 100644 index 0000000..d7ef454 --- /dev/null +++ b/docker-compose.yml @@ -0,0 +1,34 @@ +services: + mysql: + image: mysql:8.0 + container_name: mysql_container + restart: always + environment: + MYSQL_ROOT_PASSWORD: root + MYSQL_DATABASE: study + MYSQL_USER: student + MYSQL_PASSWORD: studentpw + TZ: Asia/Seoul + ports: + - "3306:3306" + volumes: + - ./db/mysql/data:/var/lib/mysql + - ./db/mysql/init:/docker-entrypoint-initdb.d + networks: + - devops-study + + redis: + image: redis:7.0 + container_name: redis_container + restart: always + command: redis-server --requirepass studentpw + ports: + - "6379:6379" + volumes: + - ./db/redis/data:/data + networks: + - devops-study + +networks: + devops-study: + driver: bridge \ No newline at end of file diff --git a/src/main/java/devops/study/base/DevopsBaseApplication.java b/src/main/java/devops/study/base/DevopsBaseApplication.java index 4ce12d3..e3b1ae0 100644 --- a/src/main/java/devops/study/base/DevopsBaseApplication.java +++ b/src/main/java/devops/study/base/DevopsBaseApplication.java @@ -9,5 +9,4 @@ public class DevopsBaseApplication { public static void main(String[] args) { SpringApplication.run(DevopsBaseApplication.class, args); } - } diff --git a/src/main/resources/application.properties b/src/main/resources/application.properties deleted file mode 100644 index eecd1f0..0000000 --- a/src/main/resources/application.properties +++ /dev/null @@ -1 +0,0 @@ -spring.application.name=devops-base From adc8b07c717474434d775625f7c745c0fa5afc70 Mon Sep 17 00:00:00 2001 From: Jinseong01 <147074506+Jinseong01@users.noreply.github.com> Date: Wed, 12 Nov 2025 03:36:22 +0900 Subject: [PATCH 02/14] =?UTF-8?q?chore:=20CI/CD=20=EC=9B=8C=ED=81=AC?= =?UTF-8?q?=ED=94=8C=EB=A1=9C=EC=9A=B0=20=EA=B5=AC=EC=B6=95=20=EB=B0=8F=20?= =?UTF-8?q?dev=20=ED=99=98=EA=B2=BD=20=EB=B0=B0=ED=8F=AC=20(#4)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - TEST.yml: 코드 빌드 및 테스트 검증 - CICD.yml: Gradle 빌드, Docker 이미지 빌드/Push, dev EC2 배포 - prod 환경 배포는 추후 설정 예정 - Redis GitHub Action 태그 수정 - TEST.yml contents read 권한 추가 --- .github/workflows/CICD.yml | 134 +++++++++++++++++++++++++++++++++++++ .github/workflows/TEST.yml | 75 +++++++++++++++++++++ Dockerfile | 13 ++++ config | 2 +- docker-compose.server.yml | 39 +++++++++++ 5 files changed, 262 insertions(+), 1 deletion(-) create mode 100644 .github/workflows/CICD.yml create mode 100644 .github/workflows/TEST.yml create mode 100644 Dockerfile create mode 100644 docker-compose.server.yml diff --git a/.github/workflows/CICD.yml b/.github/workflows/CICD.yml new file mode 100644 index 0000000..b722e7a --- /dev/null +++ b/.github/workflows/CICD.yml @@ -0,0 +1,134 @@ +name: Build and Deploy + +on: + workflow_dispatch: + push: + branches: ["main", "develop"] + +permissions: + contents: read + +jobs: + build-and-push-docker: + runs-on: ubuntu-latest + steps: + # 코드 체크아웃 (서브모듈 포함) + - name: Checkout With Submodule + uses: actions/checkout@v4 + with: + submodules: recursive + token: ${{ secrets.PERSONAL_ACCESS_TOKEN }} + fetch-depth: 0 + + # JDK 21 설치 + - name: Set up JDK 21 + uses: actions/setup-java@v4 + with: + java-version: '21' + distribution: 'temurin' + + # Gradle wrapper 실행 권한 부여 + - name: Grant execute permission for gradlew + run: chmod +x gradlew + + # Gradle 빌드 (테스트 제외) + - name: Build with Gradle + run: ./gradlew clean build -x test + + # Docker Hub 로그인 + - name: DockerHub Login + uses: docker/login-action@v3 + with: + username: ${{ secrets.DOCKER_ID }} + password: ${{ secrets.DOCKER_PASSWORD }} + + # Docker 이미지 빌드 & 푸시 + - name: Docker build & Push + run: | + docker build -t ${{ secrets.DOCKER_ID }}/${{ secrets.DOCKER_REPOSITORY }}:${{ github.ref_name }}-${{ github.sha }} . + docker push ${{ secrets.DOCKER_ID }}/${{ secrets.DOCKER_REPOSITORY }}:${{ github.ref_name }}-${{ github.sha }} + + deploy: + needs: build-and-push-docker + runs-on: self-hosted + steps: + # 배포 환경 변수 설정 + - name: Set deployment target + id: deploy-env + run: | + if [[ "${{ github.ref_name }}" == "main" ]]; then + echo "EC2_HOST=${{ secrets.EC2_PROD_HOST }}" >> $GITHUB_OUTPUT + echo "PROFILE=prod" >> $GITHUB_OUTPUT + echo "DB_URL=${{ secrets.DB_PROD_URL }}" >> $GITHUB_OUTPUT + echo "DB_USERNAME=${{ secrets.DB_PROD_USERNAME }}" >> $GITHUB_OUTPUT + echo "DB_PASSWORD=${{ secrets.DB_PROD_PASSWORD }}" >> $GITHUB_OUTPUT + echo "REDIS_PASSWORD=${{ secrets.REDIS_PROD_PASSWORD }}" >> $GITHUB_OUTPUT + else + echo "EC2_HOST=${{ secrets.EC2_DEV_HOST }}" >> $GITHUB_OUTPUT + echo "PROFILE=dev" >> $GITHUB_OUTPUT + echo "DB_URL=${{ secrets.DB_DEV_URL }}" >> $GITHUB_OUTPUT + echo "DB_USERNAME=${{ secrets.DB_DEV_USERNAME }}" >> $GITHUB_OUTPUT + echo "DB_PASSWORD=${{ secrets.DB_DEV_PASSWORD }}" >> $GITHUB_OUTPUT + echo "REDIS_PASSWORD=${{ secrets.REDIS_DEV_PASSWORD }}" >> $GITHUB_OUTPUT + fi + + # docker-compose.server.yml 체크아웃 + - name: Checkout + uses: actions/checkout@v4 + with: + sparse-checkout: | + docker-compose.server.yml + sparse-checkout-cone-mode: false + + # SSH Key 설정 + - name: Setup SSH Key + run: | + mkdir -p ~/.ssh + chmod 700 ~/.ssh + if [[ "${{ github.ref_name }}" == "main" ]]; then + echo "${{ secrets.EC2_PROD_PEM_KEY }}" > ~/.ssh/deploy_key.pem + else + echo "${{ secrets.EC2_DEV_PEM_KEY }}" > ~/.ssh/deploy_key.pem + fi + chmod 600 ~/.ssh/deploy_key.pem + + # EC2로 docker-compose.server.yml 복사 + - name: Copy docker-compose file to EC2 + run: | + scp -o StrictHostKeyChecking=no \ + -i ~/.ssh/deploy_key.pem \ + docker-compose.server.yml \ + ubuntu@${{ steps.deploy-env.outputs.EC2_HOST }}:/home/ubuntu/ + + # EC2에 배포 + - name: Deploy to EC2 + run: | + ssh -o StrictHostKeyChecking=no \ + -i ~/.ssh/deploy_key.pem \ + ubuntu@${{ steps.deploy-env.outputs.EC2_HOST }} << 'ENDSSH' + cd /home/ubuntu + + # Docker Hub 로그인 + echo "${{ secrets.DOCKER_PASSWORD }}" | docker login -u "${{ secrets.DOCKER_ID }}" --password-stdin + + # 최신 이미지 Pull + docker pull ${{ secrets.DOCKER_ID }}/${{ secrets.DOCKER_REPOSITORY }}:${{ github.ref_name }}-${{ github.sha }} + + # Docker Compose 실행 + DOCKER_IMAGE="${{ secrets.DOCKER_ID }}/${{ secrets.DOCKER_REPOSITORY }}:${{ github.ref_name }}-${{ github.sha }}" \ + SPRING_PROFILE="${{ steps.deploy-env.outputs.PROFILE }}" \ + DB_URL="${{ steps.deploy-env.outputs.DB_URL }}" \ + DB_USERNAME="${{ steps.deploy-env.outputs.DB_USERNAME }}" \ + DB_PASSWORD="${{ steps.deploy-env.outputs.DB_PASSWORD }}" \ + REDIS_PASSWORD="${{ steps.deploy-env.outputs.REDIS_PASSWORD }}" \ + docker-compose -f docker-compose.server.yml up -d + + # 사용하지 않는 Docker 리소스 정리 + docker system prune -f + ENDSSH + + # SSH Key 정리 + - name: Cleanup SSH Key + if: always() + run: | + rm -f ~/.ssh/deploy_key.pem \ No newline at end of file diff --git a/.github/workflows/TEST.yml b/.github/workflows/TEST.yml new file mode 100644 index 0000000..7e14059 --- /dev/null +++ b/.github/workflows/TEST.yml @@ -0,0 +1,75 @@ +name: Test + +on: + workflow_dispatch: + push: + branches-ignore: + - main + - develop + pull_request: + branches: ["main", "develop"] + +permissions: + contents: read + checks: write + pull-requests: write + +jobs: + build: + runs-on: ubuntu-latest + + steps: + # 코드 체크아웃 (서브모듈 포함) + - name: Checkout With Submodule + uses: actions/checkout@v4 + with: + submodules: recursive + token: ${{ secrets.PERSONAL_ACCESS_TOKEN }} + fetch-depth: 0 + + # JDK 21 설치 + - name: Set up JDK 21 + uses: actions/setup-java@v4 + with: + java-version: '21' + distribution: 'temurin' + + # Redis 서비스 시작 + - name: Start Redis + uses: supercharge/redis-github-action@1.7.0 + with: + redis-version: 7 + + # Gradle 캐시 설정 + - name: Cache Gradle + uses: actions/cache@v3 + with: + path: | + ~/.gradle/caches + ~/.gradle/wrapper + key: ${{ runner.os }}-gradle-${{ hashFiles('**/*.gradle*', '**/gradle-wrapper.properties') }} + restore-keys: | + ${{ runner.os }}-gradle- + + # Gradle wrapper 실행 권한 부여 + - name: Grant execute permission for gradlew + run: chmod +x gradlew + + # 빌드 및 테스트 실행 + - name: Build and Test + run: ./gradlew clean build -Dspring.profiles.active=test + continue-on-error: true + + # 테스트 결과 보고 + - name: Report Test Results + uses: EnricoMi/publish-unit-test-result-action@v2 + if: always() + with: + files: '**/build/test-results/test/TEST-*.xml' + + # PR에 테스트 결과 코멘트 추가 + - name: Comment Test Summary on PR + uses: mikepenz/action-junit-report@v3 + if: always() + with: + report_paths: '**/build/test-results/test/TEST-*.xml' \ No newline at end of file diff --git a/Dockerfile b/Dockerfile new file mode 100644 index 0000000..4ebbd93 --- /dev/null +++ b/Dockerfile @@ -0,0 +1,13 @@ +FROM eclipse-temurin:21-jre-jammy + +WORKDIR /app + +COPY build/libs/*.jar app.jar + +RUN addgroup --system appgroup && adduser --system --ingroup appgroup appuser +RUN chown -R appuser:appgroup /app +USER appuser + +EXPOSE 8080 + +ENTRYPOINT ["java", "-jar", "app.jar"] \ No newline at end of file diff --git a/config b/config index dc7003d..76aff07 160000 --- a/config +++ b/config @@ -1 +1 @@ -Subproject commit dc7003d19dd6730ee415f50778e8c57379fcac91 +Subproject commit 76aff0739811d5b67363dfcb8600103055a61297 diff --git a/docker-compose.server.yml b/docker-compose.server.yml new file mode 100644 index 0000000..aa65c38 --- /dev/null +++ b/docker-compose.server.yml @@ -0,0 +1,39 @@ +services: + app: + image: ${DOCKER_IMAGE} + container_name: springboot_container + restart: unless-stopped + environment: + - SPRING_PROFILES_ACTIVE=${SPRING_PROFILE} + - TZ=Asia/Seoul + - DB_URL=${DB_URL} + - DB_USERNAME=${DB_USERNAME} + - DB_PASSWORD=${DB_PASSWORD} + - REDIS_HOST=redis + - REDIS_PORT=6379 + - REDIS_PASSWORD=${REDIS_PASSWORD} + ports: + - "8080:8080" + depends_on: + - redis + networks: + - devops-study + + redis: + image: redis:7.0 + container_name: redis_container + restart: unless-stopped + command: redis-server --requirepass ${REDIS_PASSWORD} + ports: + - "6379:6379" + volumes: + - redis-data:/data + networks: + - devops-study + +networks: + devops-study: + driver: bridge + +volumes: + redis-data: \ No newline at end of file From 0bbe106b1d886ab61537f4e302920d2a27a165f7 Mon Sep 17 00:00:00 2001 From: Jinseong01 <147074506+Jinseong01@users.noreply.github.com> Date: Wed, 12 Nov 2025 18:21:23 +0900 Subject: [PATCH 03/14] =?UTF-8?q?fix:=20docker=20compose=20=EB=B0=A9?= =?UTF-8?q?=EC=8B=9D=EC=9C=BC=EB=A1=9C=20=EB=B3=80=EA=B2=BD=20(#6)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - 호환성 문제를 위해 docker compose 방식으로 변경 - 일관된 환경에서의 실행을 위해 down 명령어 추가 --- .github/workflows/CICD.yml | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/.github/workflows/CICD.yml b/.github/workflows/CICD.yml index b722e7a..3606b48 100644 --- a/.github/workflows/CICD.yml +++ b/.github/workflows/CICD.yml @@ -9,7 +9,7 @@ permissions: contents: read jobs: - build-and-push-docker: + build: runs-on: ubuntu-latest steps: # 코드 체크아웃 (서브모듈 포함) @@ -49,7 +49,7 @@ jobs: docker push ${{ secrets.DOCKER_ID }}/${{ secrets.DOCKER_REPOSITORY }}:${{ github.ref_name }}-${{ github.sha }} deploy: - needs: build-and-push-docker + needs: build runs-on: self-hosted steps: # 배포 환경 변수 설정 @@ -106,6 +106,8 @@ jobs: ssh -o StrictHostKeyChecking=no \ -i ~/.ssh/deploy_key.pem \ ubuntu@${{ steps.deploy-env.outputs.EC2_HOST }} << 'ENDSSH' + + set -e cd /home/ubuntu # Docker Hub 로그인 @@ -114,6 +116,9 @@ jobs: # 최신 이미지 Pull docker pull ${{ secrets.DOCKER_ID }}/${{ secrets.DOCKER_REPOSITORY }}:${{ github.ref_name }}-${{ github.sha }} + # 기존 컨테이너 중지 및 제거 + docker compose -f docker-compose.server.yml down + # Docker Compose 실행 DOCKER_IMAGE="${{ secrets.DOCKER_ID }}/${{ secrets.DOCKER_REPOSITORY }}:${{ github.ref_name }}-${{ github.sha }}" \ SPRING_PROFILE="${{ steps.deploy-env.outputs.PROFILE }}" \ @@ -121,7 +126,7 @@ jobs: DB_USERNAME="${{ steps.deploy-env.outputs.DB_USERNAME }}" \ DB_PASSWORD="${{ steps.deploy-env.outputs.DB_PASSWORD }}" \ REDIS_PASSWORD="${{ steps.deploy-env.outputs.REDIS_PASSWORD }}" \ - docker-compose -f docker-compose.server.yml up -d + docker compose -f docker-compose.server.yml up -d # 사용하지 않는 Docker 리소스 정리 docker system prune -f From 9dc9c97e14be5eee83381f59c511424a3addd717 Mon Sep 17 00:00:00 2001 From: Jinseong01 <147074506+Jinseong01@users.noreply.github.com> Date: Wed, 12 Nov 2025 20:04:24 +0900 Subject: [PATCH 04/14] =?UTF-8?q?fix:=20SSH=20=EB=B0=B0=ED=8F=AC=20?= =?UTF-8?q?=EC=8B=9C=20Docker=20Compose=20=ED=99=98=EA=B2=BD=EB=B3=80?= =?UTF-8?q?=EC=88=98=20=EC=A3=BC=EC=9E=85=20=EB=AC=B8=EC=A0=9C=20=ED=95=B4?= =?UTF-8?q?=EA=B2=B0=20(#8)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .github/workflows/CICD.yml | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/.github/workflows/CICD.yml b/.github/workflows/CICD.yml index 3606b48..7782510 100644 --- a/.github/workflows/CICD.yml +++ b/.github/workflows/CICD.yml @@ -105,7 +105,7 @@ jobs: run: | ssh -o StrictHostKeyChecking=no \ -i ~/.ssh/deploy_key.pem \ - ubuntu@${{ steps.deploy-env.outputs.EC2_HOST }} << 'ENDSSH' + ubuntu@${{ steps.deploy-env.outputs.EC2_HOST }} << ENDSSH set -e cd /home/ubuntu @@ -120,12 +120,12 @@ jobs: docker compose -f docker-compose.server.yml down # Docker Compose 실행 - DOCKER_IMAGE="${{ secrets.DOCKER_ID }}/${{ secrets.DOCKER_REPOSITORY }}:${{ github.ref_name }}-${{ github.sha }}" \ - SPRING_PROFILE="${{ steps.deploy-env.outputs.PROFILE }}" \ - DB_URL="${{ steps.deploy-env.outputs.DB_URL }}" \ - DB_USERNAME="${{ steps.deploy-env.outputs.DB_USERNAME }}" \ - DB_PASSWORD="${{ steps.deploy-env.outputs.DB_PASSWORD }}" \ - REDIS_PASSWORD="${{ steps.deploy-env.outputs.REDIS_PASSWORD }}" \ + export DOCKER_IMAGE="${{ secrets.DOCKER_ID }}/${{ secrets.DOCKER_REPOSITORY }}:${{ github.ref_name }}-${{ github.sha }}" + export SPRING_PROFILE="${{ steps.deploy-env.outputs.PROFILE }}" + export DB_URL="${{ steps.deploy-env.outputs.DB_URL }}" + export DB_USERNAME="${{ steps.deploy-env.outputs.DB_USERNAME }}" + export DB_PASSWORD="${{ steps.deploy-env.outputs.DB_PASSWORD }}" + export REDIS_PASSWORD="${{ steps.deploy-env.outputs.REDIS_PASSWORD }}" docker compose -f docker-compose.server.yml up -d # 사용하지 않는 Docker 리소스 정리 From d57cadfb996a19db5e7c8f1fb11b31d21a07e568 Mon Sep 17 00:00:00 2001 From: Jinseong01 <147074506+Jinseong01@users.noreply.github.com> Date: Wed, 12 Nov 2025 20:33:06 +0900 Subject: [PATCH 05/14] =?UTF-8?q?fix:=20docker=20compose=20down=20?= =?UTF-8?q?=EC=8B=A4=ED=96=89=20=EC=9C=84=EC=B9=98=20=EB=B3=80=EA=B2=BD=20?= =?UTF-8?q?(#10)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .github/workflows/CICD.yml | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/.github/workflows/CICD.yml b/.github/workflows/CICD.yml index 7782510..47303de 100644 --- a/.github/workflows/CICD.yml +++ b/.github/workflows/CICD.yml @@ -105,7 +105,7 @@ jobs: run: | ssh -o StrictHostKeyChecking=no \ -i ~/.ssh/deploy_key.pem \ - ubuntu@${{ steps.deploy-env.outputs.EC2_HOST }} << ENDSSH + ubuntu@${{ steps.deploy-env.outputs.EC2_HOST }} << 'ENDSSH' set -e cd /home/ubuntu @@ -116,16 +116,16 @@ jobs: # 최신 이미지 Pull docker pull ${{ secrets.DOCKER_ID }}/${{ secrets.DOCKER_REPOSITORY }}:${{ github.ref_name }}-${{ github.sha }} - # 기존 컨테이너 중지 및 제거 - docker compose -f docker-compose.server.yml down + # 환경변수 설정 + DOCKER_IMAGE="${{ secrets.DOCKER_ID }}/${{ secrets.DOCKER_REPOSITORY }}:${{ github.ref_name }}-${{ github.sha }}" \ + SPRING_PROFILE="${{ steps.deploy-env.outputs.PROFILE }}" \ + DB_URL="${{ steps.deploy-env.outputs.DB_URL }}" \ + DB_USERNAME="${{ steps.deploy-env.outputs.DB_USERNAME }}" \ + DB_PASSWORD="${{ steps.deploy-env.outputs.DB_PASSWORD }}" \ + REDIS_PASSWORD="${{ steps.deploy-env.outputs.REDIS_PASSWORD }}" \ - # Docker Compose 실행 - export DOCKER_IMAGE="${{ secrets.DOCKER_ID }}/${{ secrets.DOCKER_REPOSITORY }}:${{ github.ref_name }}-${{ github.sha }}" - export SPRING_PROFILE="${{ steps.deploy-env.outputs.PROFILE }}" - export DB_URL="${{ steps.deploy-env.outputs.DB_URL }}" - export DB_USERNAME="${{ steps.deploy-env.outputs.DB_USERNAME }}" - export DB_PASSWORD="${{ steps.deploy-env.outputs.DB_PASSWORD }}" - export REDIS_PASSWORD="${{ steps.deploy-env.outputs.REDIS_PASSWORD }}" + # 기존 컨테이너 정리 및 새로운 컨테이너 실행 + docker compose -f docker-compose.server.yml down docker compose -f docker-compose.server.yml up -d # 사용하지 않는 Docker 리소스 정리 From 4b53ffdcc6b276c59df8efb95a65e3e5296aa31d Mon Sep 17 00:00:00 2001 From: Jinseong01 <147074506+Jinseong01@users.noreply.github.com> Date: Wed, 12 Nov 2025 20:46:05 +0900 Subject: [PATCH 06/14] =?UTF-8?q?fix:=20export=20=ED=99=98=EA=B2=BD?= =?UTF-8?q?=EB=B3=80=EC=88=98=20=EC=84=A4=EC=A0=95=20=EB=B0=A9=EC=8B=9D=20?= =?UTF-8?q?=EC=9E=AC=EC=A0=81=EC=9A=A9=20(#11)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .github/workflows/CICD.yml | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/.github/workflows/CICD.yml b/.github/workflows/CICD.yml index 47303de..fb19b08 100644 --- a/.github/workflows/CICD.yml +++ b/.github/workflows/CICD.yml @@ -105,7 +105,7 @@ jobs: run: | ssh -o StrictHostKeyChecking=no \ -i ~/.ssh/deploy_key.pem \ - ubuntu@${{ steps.deploy-env.outputs.EC2_HOST }} << 'ENDSSH' + ubuntu@${{ steps.deploy-env.outputs.EC2_HOST }} << ENDSSH set -e cd /home/ubuntu @@ -117,12 +117,12 @@ jobs: docker pull ${{ secrets.DOCKER_ID }}/${{ secrets.DOCKER_REPOSITORY }}:${{ github.ref_name }}-${{ github.sha }} # 환경변수 설정 - DOCKER_IMAGE="${{ secrets.DOCKER_ID }}/${{ secrets.DOCKER_REPOSITORY }}:${{ github.ref_name }}-${{ github.sha }}" \ - SPRING_PROFILE="${{ steps.deploy-env.outputs.PROFILE }}" \ - DB_URL="${{ steps.deploy-env.outputs.DB_URL }}" \ - DB_USERNAME="${{ steps.deploy-env.outputs.DB_USERNAME }}" \ - DB_PASSWORD="${{ steps.deploy-env.outputs.DB_PASSWORD }}" \ - REDIS_PASSWORD="${{ steps.deploy-env.outputs.REDIS_PASSWORD }}" \ + export DOCKER_IMAGE="${{ secrets.DOCKER_ID }}/${{ secrets.DOCKER_REPOSITORY }}:${{ github.ref_name }}-${{ github.sha }}" + export SPRING_PROFILE="${{ steps.deploy-env.outputs.PROFILE }}" + export DB_URL="${{ steps.deploy-env.outputs.DB_URL }}" + export DB_USERNAME="${{ steps.deploy-env.outputs.DB_USERNAME }}" + export DB_PASSWORD="${{ steps.deploy-env.outputs.DB_PASSWORD }}" + export REDIS_PASSWORD="${{ steps.deploy-env.outputs.REDIS_PASSWORD }}" # 기존 컨테이너 정리 및 새로운 컨테이너 실행 docker compose -f docker-compose.server.yml down From e632f586bd1cb142d27992f2641111dc0e781fed Mon Sep 17 00:00:00 2001 From: Jinseong01 <147074506+Jinseong01@users.noreply.github.com> Date: Thu, 13 Nov 2025 00:18:39 +0900 Subject: [PATCH 07/14] =?UTF-8?q?chore:=20CICD=20=EB=94=94=EC=8A=A4?= =?UTF-8?q?=EC=BD=94=EB=93=9C=20=EC=9B=B9=ED=9B=85=20=EC=97=B0=EB=8F=99=20?= =?UTF-8?q?(#13)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - CICD.yml에 개발서버, 운영서버 구분 후 배포결과를 Discord로 알림 --- .github/workflows/CICD.yml | 14 +++++++++++++- 1 file changed, 13 insertions(+), 1 deletion(-) diff --git a/.github/workflows/CICD.yml b/.github/workflows/CICD.yml index fb19b08..703da13 100644 --- a/.github/workflows/CICD.yml +++ b/.github/workflows/CICD.yml @@ -136,4 +136,16 @@ jobs: - name: Cleanup SSH Key if: always() run: | - rm -f ~/.ssh/deploy_key.pem \ No newline at end of file + rm -f ~/.ssh/deploy_key.pem + + # 결과 알림 + - name: Notify Discord + uses: Ilshidur/action-discord@master + env: + DISCORD_WEBHOOK: ${{ github.ref_name == 'main' && secrets.DISCORD_MAIN_WEBHOOK || secrets.DISCORD_DEV_WEBHOOK }} + with: + args: | + 배포 결과: ${{ job.status == 'success' && '✅ 서버 배포 성공' || '❌ 서버 배포 실패' }} + - 브랜치: ${{ github.ref_name }} + - 서버: ${{ steps.deploy-env.outputs.EC2_HOST }} + - 로그: ${{ job.status == 'success' && '-' || '[Actions에서 확인](https://github.com/${{ github.repository }}/actions/runs/${{ github.run_id }})' }} \ No newline at end of file From a75f43e7954d87d5de9919bd6668a30c72778237 Mon Sep 17 00:00:00 2001 From: Jinseong01 <147074506+Jinseong01@users.noreply.github.com> Date: Thu, 13 Nov 2025 00:34:40 +0900 Subject: [PATCH 08/14] =?UTF-8?q?fix:=20Discord=20=EC=95=8C=EB=A6=BC=20?= =?UTF-8?q?=ED=95=AD=EC=83=81=20=EC=8B=A4=ED=96=89=EB=90=98=EB=8F=84?= =?UTF-8?q?=EB=A1=9D=20=EC=88=98=EC=A0=95=20(#15)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .github/workflows/CICD.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/.github/workflows/CICD.yml b/.github/workflows/CICD.yml index 703da13..7093493 100644 --- a/.github/workflows/CICD.yml +++ b/.github/workflows/CICD.yml @@ -140,6 +140,7 @@ jobs: # 결과 알림 - name: Notify Discord + if: always() uses: Ilshidur/action-discord@master env: DISCORD_WEBHOOK: ${{ github.ref_name == 'main' && secrets.DISCORD_MAIN_WEBHOOK || secrets.DISCORD_DEV_WEBHOOK }} From 69bce266205125ce3ba29778884b39c6b422ae19 Mon Sep 17 00:00:00 2001 From: Jinseong01 <147074506+Jinseong01@users.noreply.github.com> Date: Thu, 13 Nov 2025 01:07:02 +0900 Subject: [PATCH 09/14] =?UTF-8?q?fix:=20Discord=20=EC=95=8C=EB=A6=BC?= =?UTF-8?q?=EC=97=90=EC=84=9C=20=ED=95=AD=EC=83=81=20=EB=A1=9C=EA=B7=B8=20?= =?UTF-8?q?=EB=B3=B4=EC=9D=B4=EB=8F=84=EB=A1=9D=20=EC=88=98=EC=A0=95=20(#1?= =?UTF-8?q?7)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .github/workflows/CICD.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/CICD.yml b/.github/workflows/CICD.yml index 7093493..4ade895 100644 --- a/.github/workflows/CICD.yml +++ b/.github/workflows/CICD.yml @@ -149,4 +149,4 @@ jobs: 배포 결과: ${{ job.status == 'success' && '✅ 서버 배포 성공' || '❌ 서버 배포 실패' }} - 브랜치: ${{ github.ref_name }} - 서버: ${{ steps.deploy-env.outputs.EC2_HOST }} - - 로그: ${{ job.status == 'success' && '-' || '[Actions에서 확인](https://github.com/${{ github.repository }}/actions/runs/${{ github.run_id }})' }} \ No newline at end of file + - 로그: https://github.com/${{ github.repository }}/actions/runs/${{ github.run_id }} \ No newline at end of file From 408f3f9ecd675011059a05d65f39c072c40bb256 Mon Sep 17 00:00:00 2001 From: Jinseong01 <147074506+Jinseong01@users.noreply.github.com> Date: Sat, 15 Nov 2025 15:57:51 +0900 Subject: [PATCH 10/14] =?UTF-8?q?chore:=20Nginx=20=EA=B8=B0=EB=B0=98=20Blu?= =?UTF-8?q?e-Green=20=EB=AC=B4=EC=A4=91=EB=8B=A8=20=EB=B0=B0=ED=8F=AC=20?= =?UTF-8?q?=EB=8F=84=EC=9E=85=20(#19)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - server-deploy.sh: Blue/Green 앱 컨테이너 무중단 배포 및 초기 인프라 실행 - docker-compose.infra.yml: Nginx, Redis 관리 - docker-compose.server.yml: blue/green 앱 컨테이너 관리 - CICD.yml: 도커 컨테이너 실행 흐름을 스크립트 기반으로 수정 - nginx.conf: 리버스 프록시 설정 - 로그 디렉터리 수동 생성으로 변경 --- .github/workflows/CICD.yml | 33 ++++++--------- deploy/docker-compose.infra.yml | 31 ++++++++++++++ deploy/docker-compose.server.yml | 40 +++++++++++++++++ deploy/nginx.conf | 34 +++++++++++++++ deploy/server-deploy.sh | 73 ++++++++++++++++++++++++++++++++ docker-compose.server.yml | 39 ----------------- 6 files changed, 191 insertions(+), 59 deletions(-) create mode 100644 deploy/docker-compose.infra.yml create mode 100644 deploy/docker-compose.server.yml create mode 100644 deploy/nginx.conf create mode 100644 deploy/server-deploy.sh delete mode 100644 docker-compose.server.yml diff --git a/.github/workflows/CICD.yml b/.github/workflows/CICD.yml index 4ade895..071c993 100644 --- a/.github/workflows/CICD.yml +++ b/.github/workflows/CICD.yml @@ -77,7 +77,9 @@ jobs: uses: actions/checkout@v4 with: sparse-checkout: | - docker-compose.server.yml + deploy/docker-compose.server.yml + deploy/docker-compose.infra.yml + deploy/server-deploy.sh sparse-checkout-cone-mode: false # SSH Key 설정 @@ -92,13 +94,13 @@ jobs: fi chmod 600 ~/.ssh/deploy_key.pem - # EC2로 docker-compose.server.yml 복사 - - name: Copy docker-compose file to EC2 + # EC2로 docker-compose.server.yml, server-deploy.sh 복사 + - name: Prepare remote directories and copy files run: | - scp -o StrictHostKeyChecking=no \ - -i ~/.ssh/deploy_key.pem \ - docker-compose.server.yml \ - ubuntu@${{ steps.deploy-env.outputs.EC2_HOST }}:/home/ubuntu/ + ssh -o StrictHostKeyChecking=no -i ~/.ssh/deploy_key.pem ubuntu@${{ steps.deploy-env.outputs.EC2_HOST }} \ + "mkdir -p /home/ubuntu/deploy" + + scp -o StrictHostKeyChecking=no -i ~/.ssh/deploy_key.pem -r deploy/* ubuntu@${{ steps.deploy-env.outputs.EC2_HOST }}:/home/ubuntu/deploy/ # EC2에 배포 - name: Deploy to EC2 @@ -110,12 +112,6 @@ jobs: set -e cd /home/ubuntu - # Docker Hub 로그인 - echo "${{ secrets.DOCKER_PASSWORD }}" | docker login -u "${{ secrets.DOCKER_ID }}" --password-stdin - - # 최신 이미지 Pull - docker pull ${{ secrets.DOCKER_ID }}/${{ secrets.DOCKER_REPOSITORY }}:${{ github.ref_name }}-${{ github.sha }} - # 환경변수 설정 export DOCKER_IMAGE="${{ secrets.DOCKER_ID }}/${{ secrets.DOCKER_REPOSITORY }}:${{ github.ref_name }}-${{ github.sha }}" export SPRING_PROFILE="${{ steps.deploy-env.outputs.PROFILE }}" @@ -124,12 +120,9 @@ jobs: export DB_PASSWORD="${{ steps.deploy-env.outputs.DB_PASSWORD }}" export REDIS_PASSWORD="${{ steps.deploy-env.outputs.REDIS_PASSWORD }}" - # 기존 컨테이너 정리 및 새로운 컨테이너 실행 - docker compose -f docker-compose.server.yml down - docker compose -f docker-compose.server.yml up -d - - # 사용하지 않는 Docker 리소스 정리 - docker system prune -f + # Blue-Green 배포 스크립트 실행 + chmod +x /home/ubuntu/deploy/server-deploy.sh + /home/ubuntu/deploy/server-deploy.sh ENDSSH # SSH Key 정리 @@ -146,7 +139,7 @@ jobs: DISCORD_WEBHOOK: ${{ github.ref_name == 'main' && secrets.DISCORD_MAIN_WEBHOOK || secrets.DISCORD_DEV_WEBHOOK }} with: args: | - 배포 결과: ${{ job.status == 'success' && '✅ 서버 배포 성공' || '❌ 서버 배포 실패' }} + 배포 결과: ${{ job.status == 'success' && '✅ 서버 배포 성공(Blue-Green 전환 완료)' || '❌ 서버 배포 실패 (기존 컨테이너 유지)' }} - 브랜치: ${{ github.ref_name }} - 서버: ${{ steps.deploy-env.outputs.EC2_HOST }} - 로그: https://github.com/${{ github.repository }}/actions/runs/${{ github.run_id }} \ No newline at end of file diff --git a/deploy/docker-compose.infra.yml b/deploy/docker-compose.infra.yml new file mode 100644 index 0000000..d5bd810 --- /dev/null +++ b/deploy/docker-compose.infra.yml @@ -0,0 +1,31 @@ +services: + redis: + image: redis:7.0 + container_name: redis_container + restart: unless-stopped + command: redis-server --requirepass ${REDIS_PASSWORD} --appendonly yes + ports: + - "6379:6379" + volumes: + - redis-data:/data + networks: + - devops-study + + nginx: + image: nginx:alpine + container_name: nginx_container + restart: unless-stopped + volumes: + - /home/ubuntu/nginx/nginx.conf:/etc/nginx/nginx.conf:ro + - /home/ubuntu/nginx/logs:/var/log/nginx + ports: + - "80:80" + networks: + - devops-study + +networks: + devops-study: + external: true + +volumes: + redis-data: \ No newline at end of file diff --git a/deploy/docker-compose.server.yml b/deploy/docker-compose.server.yml new file mode 100644 index 0000000..de06560 --- /dev/null +++ b/deploy/docker-compose.server.yml @@ -0,0 +1,40 @@ +services: + app_blue: + image: ${DOCKER_IMAGE} + container_name: springboot_blue_container + restart: unless-stopped + environment: + - SPRING_PROFILES_ACTIVE=${SPRING_PROFILE} + - TZ=Asia/Seoul + - DB_URL=${DB_URL} + - DB_USERNAME=${DB_USERNAME} + - DB_PASSWORD=${DB_PASSWORD} + - REDIS_HOST=redis_container + - REDIS_PORT=6379 + - REDIS_PASSWORD=${REDIS_PASSWORD} + ports: + - "8081:8080" + networks: + - devops-study + + app_green: + image: ${DOCKER_IMAGE} + container_name: springboot_green_container + restart: unless-stopped + environment: + - SPRING_PROFILES_ACTIVE=${SPRING_PROFILE} + - TZ=Asia/Seoul + - DB_URL=${DB_URL} + - DB_USERNAME=${DB_USERNAME} + - DB_PASSWORD=${DB_PASSWORD} + - REDIS_HOST=redis_container + - REDIS_PORT=6379 + - REDIS_PASSWORD=${REDIS_PASSWORD} + ports: + - "8082:8080" + networks: + - devops-study + +networks: + devops-study: + external: true \ No newline at end of file diff --git a/deploy/nginx.conf b/deploy/nginx.conf new file mode 100644 index 0000000..d7f1325 --- /dev/null +++ b/deploy/nginx.conf @@ -0,0 +1,34 @@ +worker_processes auto; + +events { + worker_connections 1024; +} + +http { + # 활성 서버 설정 + upstream backend { + server springboot_blue_container:8080; + } + + server { + listen 80; + + # 메인 트래픽 + location / { + proxy_pass http://backend; + proxy_set_header Host $host; + proxy_set_header X-Real-IP $remote_addr; + proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; + proxy_set_header X-Forwarded-Proto $scheme; + } + + # 로그 설정 + access_log /var/log/nginx/access.log; + error_log /var/log/nginx/error.log warn; + + # 타임아웃 설정 + proxy_connect_timeout 5s; + proxy_read_timeout 30s; + proxy_send_timeout 30s; + } +} diff --git a/deploy/server-deploy.sh b/deploy/server-deploy.sh new file mode 100644 index 0000000..2383adb --- /dev/null +++ b/deploy/server-deploy.sh @@ -0,0 +1,73 @@ +#!/bin/bash +set -e + +# 0. devops-study 네트워크 없으면 생성 +if ! docker network ls | grep -q devops-study; then + echo "📦 Docker 네트워크 생성" + docker network create devops-study +fi + +# 1. Redis, Nginx 미실행 시 실행 +for SERVICE in redis nginx; do + CONTAINER=$(docker ps --filter "name=${SERVICE}_container" --format "{{.Names}}") + if [ -z "$CONTAINER" ]; then + echo "📦 $SERVICE 실행" + docker compose -f /home/ubuntu/deploy/docker-compose.infra.yml up -d $SERVICE + fi +done + +# 2. 실행 중인 컨테이너 확인 +SPRINGBOOT_CONTAINER=$(docker ps --filter "name=springboot_" --format "{{.Names}}") + +if [ "$SPRINGBOOT_CONTAINER" == "springboot_blue_container" ]; then + NEW_PORT=8082 + NEW_SERVICE="app_green" + NEW_CONTAINER="springboot_green_container" + OLD_SERVICE="app_blue" + OLD_CONTAINER="springboot_blue_container" + echo "🟢 Green(8082) 배포 시작" +else + NEW_PORT=8081 + NEW_SERVICE="app_blue" + NEW_CONTAINER="springboot_blue_container" + OLD_SERVICE="app_green" + OLD_CONTAINER="springboot_green_container" + echo "🔵 Blue(8081) 배포 시작" +fi + +# 3. 이미지 Pull +docker pull ${DOCKER_IMAGE} + +# 4. 새 컨테이너 시작 +docker compose -f /home/ubuntu/deploy/docker-compose.server.yml up -d --no-deps ${NEW_SERVICE} + +# 헬스체크 (최대 45초) +for i in {1..9}; do + if curl -f -m 5 http://localhost:${NEW_PORT}/actuator/health > /dev/null 2>&1; then + echo "✅ $NEW_SERVICE 헬스체크 성공" + break + fi + + if [ $i -eq 9 ]; then + echo "❌ $NEW_SERVICE 헬스체크 실패" + docker compose -f /home/ubuntu/deploy/docker-compose.server.yml stop ${NEW_SERVICE} + exit 1 + fi + + echo "재시도 중... ($i/9)" + sleep 5 +done + + +# 새로운 컨테이너 헬스체크 성공한 경우만 이후 단계 진행 +# 5. Nginx 설정 변경 +sed -i "s/${OLD_CONTAINER}:8080/${NEW_CONTAINER}:8080/" /home/ubuntu/nginx/nginx.conf + +# 6. Nginx 리로드 +docker exec nginx_container nginx -s reload + +# 7. 이전 컨테이너 중지 +docker compose -f /home/ubuntu/deploy/docker-compose.server.yml stop ${OLD_SERVICE} + +# 8. 리소스 정리 +docker system prune -f > /dev/null 2>&1 \ No newline at end of file diff --git a/docker-compose.server.yml b/docker-compose.server.yml deleted file mode 100644 index aa65c38..0000000 --- a/docker-compose.server.yml +++ /dev/null @@ -1,39 +0,0 @@ -services: - app: - image: ${DOCKER_IMAGE} - container_name: springboot_container - restart: unless-stopped - environment: - - SPRING_PROFILES_ACTIVE=${SPRING_PROFILE} - - TZ=Asia/Seoul - - DB_URL=${DB_URL} - - DB_USERNAME=${DB_USERNAME} - - DB_PASSWORD=${DB_PASSWORD} - - REDIS_HOST=redis - - REDIS_PORT=6379 - - REDIS_PASSWORD=${REDIS_PASSWORD} - ports: - - "8080:8080" - depends_on: - - redis - networks: - - devops-study - - redis: - image: redis:7.0 - container_name: redis_container - restart: unless-stopped - command: redis-server --requirepass ${REDIS_PASSWORD} - ports: - - "6379:6379" - volumes: - - redis-data:/data - networks: - - devops-study - -networks: - devops-study: - driver: bridge - -volumes: - redis-data: \ No newline at end of file From 58c0e9d46c384e6995a30e774729a10dced969a3 Mon Sep 17 00:00:00 2001 From: Jinseong01 <147074506+Jinseong01@users.noreply.github.com> Date: Sat, 15 Nov 2025 16:57:35 +0900 Subject: [PATCH 11/14] =?UTF-8?q?fix:=20=EC=BB=A8=ED=85=8C=EC=9D=B4?= =?UTF-8?q?=EB=84=88=20=EB=82=B4=EB=B6=80=20nginx.conf=20=EC=88=98?= =?UTF-8?q?=EC=A0=95=20=EC=BD=94=EB=93=9C=20=EC=B6=94=EA=B0=80=20(#21)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- deploy/server-deploy.sh | 1 + 1 file changed, 1 insertion(+) diff --git a/deploy/server-deploy.sh b/deploy/server-deploy.sh index 2383adb..1c20cba 100644 --- a/deploy/server-deploy.sh +++ b/deploy/server-deploy.sh @@ -62,6 +62,7 @@ done # 새로운 컨테이너 헬스체크 성공한 경우만 이후 단계 진행 # 5. Nginx 설정 변경 sed -i "s/${OLD_CONTAINER}:8080/${NEW_CONTAINER}:8080/" /home/ubuntu/nginx/nginx.conf +docker exec nginx_container sed -i "s/${OLD_CONTAINER}:8080/${NEW_CONTAINER}:8080/" /etc/nginx/nginx.conf # 6. Nginx 리로드 docker exec nginx_container nginx -s reload From a390f40750c519f642c77f4062d8b3e702420714 Mon Sep 17 00:00:00 2001 From: Jinseong01 <147074506+Jinseong01@users.noreply.github.com> Date: Sat, 15 Nov 2025 18:37:04 +0900 Subject: [PATCH 12/14] =?UTF-8?q?fix:=20=ED=98=B8=EC=8A=A4=ED=8A=B8=20ngin?= =?UTF-8?q?x.conf=EB=A5=BC=20i-node=20=EB=B3=80=EA=B2=BD=EC=97=86=EC=9D=B4?= =?UTF-8?q?=20=EC=88=98=EC=A0=95=20(#23)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - sed의 결과를 tee로 덮어쓰도록 변경하여 i-node 유지 - 스프링부트 컨테이너가 실행되지 않은 경우에는 blue-green 전환 스킵 --- deploy/server-deploy.sh | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-) diff --git a/deploy/server-deploy.sh b/deploy/server-deploy.sh index 1c20cba..871d488 100644 --- a/deploy/server-deploy.sh +++ b/deploy/server-deploy.sh @@ -61,14 +61,16 @@ done # 새로운 컨테이너 헬스체크 성공한 경우만 이후 단계 진행 # 5. Nginx 설정 변경 -sed -i "s/${OLD_CONTAINER}:8080/${NEW_CONTAINER}:8080/" /home/ubuntu/nginx/nginx.conf -docker exec nginx_container sed -i "s/${OLD_CONTAINER}:8080/${NEW_CONTAINER}:8080/" /etc/nginx/nginx.conf +if [ -n "$SPRINGBOOT_CONTAINER" ]; then + sed "s/${OLD_CONTAINER}:8080/${NEW_CONTAINER}:8080/" /home/ubuntu/nginx/nginx.conf | \ + tee /home/ubuntu/nginx/nginx.conf > /dev/null -# 6. Nginx 리로드 -docker exec nginx_container nginx -s reload + # 6. Nginx 리로드 + docker exec nginx_container nginx -s reload -# 7. 이전 컨테이너 중지 -docker compose -f /home/ubuntu/deploy/docker-compose.server.yml stop ${OLD_SERVICE} + # 7. 이전 컨테이너 중지 + docker compose -f /home/ubuntu/deploy/docker-compose.server.yml stop ${OLD_SERVICE} +fi # 8. 리소스 정리 docker system prune -f > /dev/null 2>&1 \ No newline at end of file From 6959fae5a0177ad26aad51955648ff0fe09b116d Mon Sep 17 00:00:00 2001 From: Jinseong01 <147074506+Jinseong01@users.noreply.github.com> Date: Sat, 15 Nov 2025 19:20:42 +0900 Subject: [PATCH 13/14] =?UTF-8?q?fix:=20nginx.conf=20=EB=B3=80=EA=B2=BD=20?= =?UTF-8?q?=EC=9E=84=EC=8B=9C=ED=8C=8C=EC=9D=BC=20=EB=B0=A9=EC=8B=9D?= =?UTF-8?q?=EC=9C=BC=EB=A1=9C=20=EC=88=98=EC=A0=95=20(#24)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- deploy/server-deploy.sh | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/deploy/server-deploy.sh b/deploy/server-deploy.sh index 871d488..9f48e07 100644 --- a/deploy/server-deploy.sh +++ b/deploy/server-deploy.sh @@ -62,8 +62,9 @@ done # 새로운 컨테이너 헬스체크 성공한 경우만 이후 단계 진행 # 5. Nginx 설정 변경 if [ -n "$SPRINGBOOT_CONTAINER" ]; then - sed "s/${OLD_CONTAINER}:8080/${NEW_CONTAINER}:8080/" /home/ubuntu/nginx/nginx.conf | \ - tee /home/ubuntu/nginx/nginx.conf > /dev/null + sed "s/${OLD_CONTAINER}:8080/${NEW_CONTAINER}:8080/" /home/ubuntu/nginx/nginx.conf > /tmp/nginx_temp.conf + cat /tmp/nginx_temp.conf > /home/ubuntu/nginx/nginx.conf + rm /tmp/nginx_temp.conf # 6. Nginx 리로드 docker exec nginx_container nginx -s reload From 2d8267f695da8b76b6c2e1543ee9e4dd140fc4b7 Mon Sep 17 00:00:00 2001 From: Jinseong Date: Mon, 17 Nov 2025 17:19:15 +0900 Subject: [PATCH 14/14] =?UTF-8?q?release:=20v1.0.0=20=EC=9A=B4=EC=98=81=20?= =?UTF-8?q?=EC=84=9C=EB=B2=84=20=EB=B0=B0=ED=8F=AC?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit