diff --git a/.github/workflows/jtoon-ci.yml b/.github/workflows/jtoon-ci.yml index a3d88741..21f5d6b4 100644 --- a/.github/workflows/jtoon-ci.yml +++ b/.github/workflows/jtoon-ci.yml @@ -1,8 +1,8 @@ -name: JToon CI +name: JToon CI/CD on: push: - branches: [ "main", "develop" ] + branches: [ "develop" ] pull_request: branches: [ "main", "develop" ] @@ -15,18 +15,28 @@ jobs: runs-on: ubuntu-latest steps: - - uses: actions/checkout@v3 - - - name: Set up JDK 17 - uses: actions/setup-java@v3 - with: - java-version: '17' - distribution: 'corretto' - - - name: Grant execute permission for gradlew - run: chmod +x gradlew - - - name: Build with Gradle - uses: gradle/gradle-build-action@bd5760595778326ba7f1441bcf7e88b49de61a25 # v2.6.0 - with: - arguments: build + - uses: actions/checkout@v3 + + - name: JDK 17 설정 + uses: actions/setup-java@v3 + with: + java-version: '17' + distribution: 'corretto' + + - name: 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- + + - name: Gradle Grant 권한 부여 + run: chmod +x gradlew + + - name: Gradle 빌드 + uses: gradle/gradle-build-action@bd5760595778326ba7f1441bcf7e88b49de61a25 # v2.6.0 + with: + arguments: build diff --git a/.github/workflows/jtoon-deploy.yml b/.github/workflows/jtoon-deploy.yml new file mode 100644 index 00000000..7e64a915 --- /dev/null +++ b/.github/workflows/jtoon-deploy.yml @@ -0,0 +1,75 @@ +name: JToon CI/CD + +on: + push: + branches: [ "main" ] + +permissions: + contents: read + +jobs: + build: + + runs-on: ubuntu-latest + + steps: + - uses: actions/checkout@v3 + + - name: 배포 버전 추출 + run: | + VERSION=$(grep -o -E "v[0-9]+\.[0-9]+\.[0-9]+" <<< "${{ github.event.head_commit.message }}") + echo "VERSION=${VERSION}" >> $GITHUB_ENV + + - name: Github release 생성 + uses: actions/create-release@v1 + with: + tag_name: ${{ env.VERSION }} + release_name: JTOON - ${{ env.VERSION }} + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + + - name: JDK 17 설정 + uses: actions/setup-java@v3 + with: + java-version: '17' + distribution: 'corretto' + + - name: 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- + + - name: 설정파일 application-prod.yml 생성 + run: | + cd ./module-application/src/main/resources + touch ./application-prod.yml + echo "${{ secrets.APPLICATION_PROD }}" > ./application-prod.yml + shell: bash + + - name: Gradle Grant 권한 부여 + run: chmod +x gradlew + + - name: Gradle 빌드 + uses: gradle/gradle-build-action@bd5760595778326ba7f1441bcf7e88b49de61a25 # v2.6.0 + with: + arguments: build + + - name: 멀티플랫폼 위한 Docker Buildx 설정 + uses: docker/setup-buildx-action@v2 + + - name: Docker Hub 로그인, 빌드, 푸쉬 + uses: docker/login-action@v2 + with: + username: ${{ secrets.DOCKER_HUB_USERNAME }} + password: ${{ secrets.DOCKER_HUB_TOKEN }} + - run: | + cd module-application + docker build -t ${{ secrets.DOCKER_HUB_USERNAME }}/${{ secrets.DOCKER_HUB_REPOSITORY }}:latest -f Dockerfile . --platform linux/x86_64 + docker push ${{ secrets.DOCKER_HUB_USERNAME }}/${{ secrets.DOCKER_HUB_REPOSITORY }}:latest + docker tag ${{ secrets.DOCKER_HUB_USERNAME }}/${{ secrets.DOCKER_HUB_REPOSITORY }}:latest ${{ secrets.DOCKER_HUB_USERNAME }}/${{ secrets.DOCKER_HUB_REPOSITORY }}:${{ env.VERSION }} + docker push ${{ secrets.DOCKER_HUB_USERNAME }}/${{ secrets.DOCKER_HUB_REPOSITORY }}:${{ env.VERSION }} diff --git a/.gitignore b/.gitignore index 93e48470..931af4dc 100644 --- a/.gitignore +++ b/.gitignore @@ -120,6 +120,3 @@ gradle-app.setting application-*.yml !application.yml - -# End of https://www.toptal.com/developers/gitignore/api/gradle -/module-application/src/main/resources/application-local-payment.yml diff --git a/infrastructure/docker-compose.yml b/infrastructure/docker-compose.yml new file mode 100644 index 00000000..861e46f8 --- /dev/null +++ b/infrastructure/docker-compose.yml @@ -0,0 +1,23 @@ +version: '3.7' + +services: + nginx: + image: nginx + container_name: nginx + restart: always + ports: + - '80:80' + volumes: + - ./nginx/:/etc/nginx/conf.d/ + jtoon-blue: + image: ${DOCKER_HUB_USERNAME}/${DOCKER_HUB_REPOSITORY}:latest + container_name: jtoon-blue + restart: always + expose: + - 8080 + jtoon-green: + image: ${DOCKER_HUB_USERNAME}/${DOCKER_HUB_REPOSITORY}:latest + container_name: jtoon-green + restart: always + expose: + - 8080 diff --git a/infrastructure/nginx/nginx.conf b/infrastructure/nginx/nginx.conf new file mode 100644 index 00000000..4065409f --- /dev/null +++ b/infrastructure/nginx/nginx.conf @@ -0,0 +1,17 @@ +upstream jtoon-server{ + server jtoon-blue:8080; +} + +server { + listen 80; + server_name api.jtoon.shop; + + location / { + proxy_pass http://jtoon-server; + proxy_redirect off; + 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-Host $server_name; + } +} diff --git a/infrastructure/scripts/deploy.sh b/infrastructure/scripts/deploy.sh new file mode 100644 index 00000000..1d84043f --- /dev/null +++ b/infrastructure/scripts/deploy.sh @@ -0,0 +1,47 @@ +#!/bin/sh + +IS_BLUE=$(docker ps | grep jtoon-blue) + +NGINX_CONF="./nginx/nginx.conf" + +docker-compose up -d nginx + +if [ $IS_BLUE ];then + echo "### BLUE => GREEN ###" + echo "1. jtoon-green 이미지 가져오고 실행" + docker-compose pull jtoon-green + docker-compose up -d jtoon-green + while [ 1 = 1 ]; do + echo "2. jtoon-green health check" + sleep 5 + REQUEST=$(docker exec nginx curl http://jtoon-green:8080) + if [ -n "$REQUEST" ]; then + echo "health check 성공" + break; + fi + done; + sed -i 's/jtoon-blue/jtoon-green/g' $NGINX_CONF + echo "3. nginx 설정파일 reload" + docker exec nginx service nginx reload + echo "4. jtoon-blue 컨테이너 종료" + docker-compose stop jtoon-blue +else + echo "### GREEN => BLUE ###" + echo "1. jtoon-blue 이미지 가져오고 실행" + docker-compose pull jtoon-blue + docker-compose up -d jtoon-blue + while [ 1 = 1 ]; do + echo "2. jtoon-blue health check" + sleep 5 + REQUEST=$(docker exec nginx curl http://jtoon-blue:8080) + if [ -n "$REQUEST" ]; then + echo "health check 성공" + break; + fi + done; + sed -i 's/jtoon-green/jtoon-blue/g' $NGINX_CONF + echo "3. nginx 설정파일 reload" + docker exec nginx service nginx reload + echo "4. jtoon-green 컨테이너 종료" + docker-compose stop jtoon-green +fi diff --git a/module-application/Dockerfile b/module-application/Dockerfile new file mode 100644 index 00000000..c7d3844d --- /dev/null +++ b/module-application/Dockerfile @@ -0,0 +1,8 @@ +### Docker 이미지를 생성할 때 기반이 되는 베이스 이미지를 설정한다. +FROM amazoncorretto:17 +### 조셉팀 ^-^ +MAINTAINER 박세연, 신재윤, 홍혁준, 김영명, 김희빈 +### 경로에 해당하는 파일을 Docker 이미지 내부로 복사한다. +COPY ${PWD}/build/libs/module-application-0.0.1-SNAPSHOT.jar jtoon.jar +### Docker 컨테이너가 시작될 때 실행할 명령을 지정한다. +ENTRYPOINT ["java", "-Dspring.profiles.active=prod", "-jar","/jtoon.jar"] diff --git a/module-application/src/main/resources/application.yml b/module-application/src/main/resources/application.yml index 0bf72a40..e69de29b 100644 --- a/module-application/src/main/resources/application.yml +++ b/module-application/src/main/resources/application.yml @@ -1,3 +0,0 @@ -spring: - profiles: - include: s3, smtp, iamport, jwt