diff --git a/.github/workflows/deploy.yml b/.github/workflows/deploy.yml new file mode 100644 index 0000000..34ff6d0 --- /dev/null +++ b/.github/workflows/deploy.yml @@ -0,0 +1,83 @@ +name: Build and Push Docker Image and Deploy + +# main, dev 브랜치에 push or PR 이 오면 실행 +on: + push: + branches: + - main + - dev + pull_request: + branches: + - main + - dev + +jobs: + # 도커 이미지 빌드, 푸시 + build_and_push: + runs-on: ubuntu-latest + + steps: + - uses: actions/checkout@v4 + + # DB 세팅 정보 입력 + - name: Set up application.yml + run: | + echo "${{ secrets.APPLICATION }}" > ./src/main/resources/application.yml + echo "${{ secrets.APPLICATION_TEST }}" > ./src/main/resources/application-test.yml + + # SSL 적용 + - name: Create SSH Key File + run: echo "${{ secrets.PRIVATE_KEY }}" > /tmp/private_key.pem + + - name: Set Permissions for SSH Key + run: chmod 600 /tmp/private_key.pem + + - name: Copy keystore.p12 from EC2 + run: scp -o StrictHostKeyChecking=no -i /tmp/private_key.pem ${{ secrets.EC2_USER }}@${{ secrets.EC2_HOST }}:/home/${{ secrets.EC2_USER }}/keystore.p12 ./src/main/resources/keystore.p12 + + # 도커 이미지 빌드용 환경 세팅 및 도커 이미지 빌드 + - name: set up test DB and docker build + run: | + docker compose -f docker-compose-auth-test-db.yml up -d # 도커 컴포즈파일로 테스트 환경 세팅 + DOCKER_BUILDKIT=0 docker build --network testNet -t ${{ secrets.DOCKER_IMAGE_NAME }}:latest . # 도커 빌드 (빌드 과정에서 네트워크 사용을 위해 빌드킷 0) + docker compose -f docker-compose-auth-test-db.yml down # 테스트 환경 제거 (네트워크까지 삭제됨) + + # 도커 로그인 + - name: docker Login + uses: docker/login-action@v3.3.0 + with: + username: ${{ secrets.DOCKER_USERNAME }} + password: ${{ secrets.DOCKER_PASSWORD }} + + # 도커 이미지 push + - name: push docker images + run: | + docker push ${{ secrets.DOCKER_IMAGE_NAME }}:latest + + # 도커 이미지 EC2 인스턴스에 배포 + deploy_to_ec2: + needs: build_and_push + runs-on: ubuntu-24.04 + + steps: + - name: Deploy to EC2 + uses: appleboy/ssh-action@master + with: + host: ${{ secrets.EC2_HOST }} # EC2 IP 주소 + username: ${{ secrets.EC2_USER }} # EC2 사용자 + key: ${{ secrets.PRIVATE_KEY }} # pem 키 + + # 기존 컨테이너 중지 + script: | + CONTAINER_ID=$(sudo docker ps -aq --filter "name=kaboo-auth") + + if [ ! -z "$CONTAINER_ID" ]; then + sudo docker stop $CONTAINER_ID || true + sudo docker rm -f $CONTAINER_ID || true + fi + + # 최신 도커 이미지로 컨테이너 실행 + sudo docker pull ${{ secrets.DOCKER_IMAGE_NAME }}:latest # 도커 최신 이미지 다운로드 + # 도커 이미지 실행 (host.docker.internal 사용 가능하도록) + docker run --name kaboo-auth -d --add-host host.docker.internal:host-gateway -p 8081:8081 ${{ secrets.DOCKER_IMAGE_NAME }}:latest + sudo docker image prune -f # 구버전의 도커 이미지 제거 diff --git a/.gitignore b/.gitignore index 655245b..c46dead 100644 --- a/.gitignore +++ b/.gitignore @@ -86,6 +86,7 @@ fabric.properties .idea/* +!.idea/codeStyles !.idea/runConfigurations ### Java ### @@ -174,8 +175,4 @@ gradle-app.setting # Java heap dump *.hprof -# End of https://www.toptal.com/developers/gitignore/api/java,gradle,macos,intellij+allauth.yml -oauth.yml -database.yml -jwt.yml -application-test.yml +# End of https://www.toptal.com/developers/gitignore/api/java,gradle,macos,intellij+all \ No newline at end of file diff --git a/Dockerfile b/Dockerfile new file mode 100644 index 0000000..eb6b700 --- /dev/null +++ b/Dockerfile @@ -0,0 +1,14 @@ +# Build +FROM eclipse-temurin:17-jdk AS build +LABEL authors="pjh5365" + +WORKDIR /src +COPY . /src +RUN ./gradlew build + +# Run +FROM eclipse-temurin:17-jre +EXPOSE 8081 +COPY --from=build /src/build/libs/*SNAPSHOT.jar kaboo-auth.jar + +ENTRYPOINT ["java", "-jar", "kaboo-auth.jar"] diff --git a/build.gradle b/build.gradle index 4ddfcfd..3827b7a 100644 --- a/build.gradle +++ b/build.gradle @@ -29,11 +29,10 @@ dependencies { implementation 'org.springframework.boot:spring-boot-starter-security' implementation 'org.springframework.boot:spring-boot-starter-web' compileOnly 'org.projectlombok:lombok' - runtimeOnly 'org.mariadb.jdbc:mariadb-java-client' + runtimeOnly 'com.h2database:h2' annotationProcessor 'org.projectlombok:lombok' testImplementation 'org.springframework.boot:spring-boot-starter-test' testImplementation 'org.springframework.security:spring-security-test' - testImplementation 'com.h2database:h2' testRuntimeOnly 'org.junit.platform:junit-platform-launcher' // JWT Token Dependency diff --git a/docker-compose-auth-test-db.yml b/docker-compose-auth-test-db.yml new file mode 100644 index 0000000..9d42339 --- /dev/null +++ b/docker-compose-auth-test-db.yml @@ -0,0 +1,15 @@ +# 테스트 DB 환경 세팅 +services: + redis: + image: redis:alpine + container_name: redis + ports: + - "6379:6379" + networks: + - testNet + +networks: + testNet: + name: testNet # 네트워크 이름 지정 + driver: bridge # 브릿지 모드 + attachable: true # 외부접속 허용 diff --git a/src/test/java/kaboo/kaboo_auth/repository/MemberRepositoryTest.java b/src/test/java/kaboo/kaboo_auth/repository/MemberRepositoryTest.java index af239d9..f436968 100644 --- a/src/test/java/kaboo/kaboo_auth/repository/MemberRepositoryTest.java +++ b/src/test/java/kaboo/kaboo_auth/repository/MemberRepositoryTest.java @@ -10,6 +10,7 @@ import org.junit.jupiter.api.Test; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.test.autoconfigure.orm.jpa.DataJpaTest; +import org.springframework.test.context.ActiveProfiles; import org.springframework.transaction.annotation.Transactional; import kaboo.kaboo_auth.domain.Course; @@ -18,6 +19,7 @@ @DataJpaTest @Transactional @DisplayName("Member Repository Test") +@ActiveProfiles("test") class MemberRepositoryTest { @Autowired MemberRepository memberRepository; diff --git a/src/test/resources/application.yml b/src/test/resources/application.yml new file mode 100644 index 0000000..01468af --- /dev/null +++ b/src/test/resources/application.yml @@ -0,0 +1,18 @@ +spring: + datasource: + url: jdbc:h2:mem:test;MODE=MariaDB;DB_CLOSE_DELAY=-1;DB_CLOSE_ON_EXIT=FALSE + username: sa + password: + driverClassName: org.h2.Driver + jpa: + database-platform: org.hibernate.dialect.H2Dialect + hibernate: + ddl-auto: update + show-sql: true + properties: + hibernate: + format_sql: true + h2: + console: + enabled: true + path: /h2-console \ No newline at end of file