diff --git a/.github/ISSUE_TEMPLATE/issue_template.md b/.github/ISSUE_TEMPLATE/issue_template.md index ceb66ed..b619f88 100644 --- a/.github/ISSUE_TEMPLATE/issue_template.md +++ b/.github/ISSUE_TEMPLATE/issue_template.md @@ -9,11 +9,14 @@ assignees: '' + + ## 💡 구현할 기능 설명 -기능에 대해 설명해주세요 +기능에 대해 설명해주세요. ## ❗체크리스트 - [ ] 모든 포지션의 팀원들이 이해할 수 있도록 충분한 설명을 제공하나요? - [ ] 제목 형식을 지키고 브랜치 및 라벨을 할당했나요? - [ ] 리뷰어와 Assignee도 할당했나요? +- [ ] 브랜치명 컨벤션을 지켜 브랜치를 생성하였나요? diff --git a/.github/pull_request_template.md b/.github/pull_request_template.md index c4903af..fa981b7 100644 --- a/.github/pull_request_template.md +++ b/.github/pull_request_template.md @@ -1,5 +1,9 @@ + + + + ## ❗️ 이슈 번호 -Closes +Closes ## 📝 작업 내용 diff --git a/.github/workflows/cicd-dev.yml b/.github/workflows/cicd-dev.yml new file mode 100644 index 0000000..150419c --- /dev/null +++ b/.github/workflows/cicd-dev.yml @@ -0,0 +1,84 @@ +name: Docker Hub Dev Deploy + +run-name: ${{ github.head_ref }} 브랜치 작업 내용 병합 후 배포 + +on: + push: + branches: + - develop + +jobs: + deploy: + runs-on: ubuntu-latest + steps: + # develop 브랜치 체크아웃 + - name: Checkout + uses: actions/checkout@v3 + + # application.yml 파일 생성 + - name: make application.yml + run: | + # create application.yml + cd ./src/main + cd .resources + + touch ./application.yml + + echo "${{ secrets.APPLICATION_DEV_YML }}" >> ./application.yml + + # 빌드 권한 부여 + - name: Grant execute permission for gradlew + run: chmod +x ./gradlew + + # docker image 빌드 + - name: Build + run: docker build --no-cache -t ${{ secrets.DOCKERHUB_USERNAME }}/${{ secrets.DOCKERHUB_IMAGE_NAME }}:${{ secrets.DOCKERHUB_IMAGE_TAG }} . + + # docker hub 로그인 + - name: Docker Hub login + uses: docker/login-action@v3 + with: + username: ${{ secretes.DOCKERHUB_USERNAME }} + password: ${{ secretes.DOCKERHUB_TOKEN_READ_WRITE }} + + # docker hub에 image push + - name: docker image push + run: docker push ${{ secrets.DOCKERHUB_USERNAME }}/${{ secrets.DOCKERHUB_IMAGE_NAME}}:${{secrets.DOCKERHUB_IMAGE_TAG }} + + # docker compose에 사용될 환경 변수들이 담긴 env 파일 세팅 + - name: Set up environment variables + run: | + echo "DOCKER_USERNAME=${{ secrets.DOCKERHUB_USERNAME }}" >> dev.env + echo "DOCKER_IMAGE_NAME=${{ secrets.DOCKERHUB_IMAGE_NAME }}" >> dev.env + echo "DOCKER_IMAGE_TAG=${{ secrets.DOCKERHUB_IMAGE_TAG }}" >> dev.env + echo "SPRING_OUTER_PORT=${{ secrets.SPRING_OUTER_PORT }}" >> dev.env + echo "SPRING_INNER_PORT=${{ secrets.SPRING_INNER_PORT }}" >> dev.env + + # compose.yml, dev.env 파일 서버로 복사 + - name: Copy compose.yml, dev.env + uses: appleboy/scp-action@master + with: + host: ${{ secrets.SSH_HOST }} + port: ${{ secrets.SSH_PORT }} + username: ${{ secrets.SSH_USERNAME }} + key: ${{ secrets.SSH_PRIVATE_KEY }} + source: "compose.yml, dev.env" + target: /home/ubuntu + + # EC2에서 docker compose up + - name: Deploy to Server + uses: appleboy/ssh-action@master + with: + host: ${{ secrets.SSH_HOST }} + port: ${{ secrets.SSH_PORT }} + username: ${{ secrets.SSH_USERNAME }} + key: ${{ secrets.SSH_PRIVATE_KEY }} + script: | + cd /home/ubuntu + sudo docker login -u ${{ secrets.DOCKERHUB_USERNAME }} -p ${{ secrets.DOCKERHUB_TOKEN_READ_ONLY }} + sudo docker container stop naoman-dev + sudo docker container rm naoman-dev + sudo docker image rm ${{ secrets.DOCKERHUB_USERNAME }}/${{ secrets.DOCKERHUB_IMAGE_NAME}}:${{secrets.DOCKERHUB_IMAGE_TAG }} + sudo docker compose --env-file dev.env -f compose.yml up -d + sudo docker container prune -f + sudo docker image prune -a -f \ No newline at end of file diff --git a/Dockerfile b/Dockerfile new file mode 100644 index 0000000..070071e --- /dev/null +++ b/Dockerfile @@ -0,0 +1,32 @@ +# base 이미지 가져오기 +# 최신 버전의 alpine 사용 +# 빌드 스테이지를 builder라고 명명 +FROM amazoncorretto:17-alpine-jdk AS builder + +# 작업 디렉토리 /app 으로 설정 +WORKDIR /app + +# gradlew, build.gradle, settings.gradle, gradle, src 복사 +COPY gradlew build.gradle settings.gradle ./ +COPY gradle ./gradle +COPY src ./src + +# jar 파일 생성을 위한 bootJar 실행 +RUN ./gradlew bootJar + +# 2번째 빌드 스테이지 +# base 이미지 가져오기 +FROM amazoncorretto:17-alpine-jdk + +# 작업 디렉토리 설정 +WORKDIR /app + +# jar 파일 가져오기 +# 이전 빌드 스테이지 'builder'에서 생성된 jar 파일을 복사 +COPY --from=builder /app/build/libs/*.jar /app/naoman.jar + +# 8080 포트를 사용함을 명시 +EXPOSE 8080 + +# 컨테이너 실행 시 naoman.jar 파일 실행 +ENTRYPOINT java -jar /app/naoman.jar \ No newline at end of file diff --git a/build.gradle b/build.gradle index a9732e5..55bb84b 100644 --- a/build.gradle +++ b/build.gradle @@ -50,7 +50,7 @@ dependencies { testImplementation 'org.springframework.security:spring-security-test' testRuntimeOnly 'org.junit.platform:junit-platform-launcher' - // AWS + // AWS, AWS S3 implementation platform("io.awspring.cloud:spring-cloud-aws-dependencies:3.0.0") implementation 'io.awspring.cloud:spring-cloud-aws-starter-s3' implementation 'org.springframework.cloud:spring-cloud-starter-aws:2.2.6.RELEASE' diff --git a/compose.yml b/compose.yml new file mode 100644 index 0000000..bb6c0b9 --- /dev/null +++ b/compose.yml @@ -0,0 +1,29 @@ +services: + spring-application: + container_name: naoman-dev + image: ${DOCKER_USERNAME}/${DOCKER_IMAGE_NAME}:${DOCKER_IMAGE_TAG} + ports: + - ${SPRING_OUTER_PORT}:${SPRING_INNER_PORT} + + nginx: + container_name: nginx-dev + image: nginx:latest + volumes: + - ./naoman/default.conf:/etc/nginx/conf.d/efault/conf + restart: always + ports: + - 80:80 + + # 설정을 6시간마다 다시 로드하여 최신 상태를 유지한다. + # 포그라운드 실행을 통해 Nginx 서버를 계속 실행시킨다. + command: [ + "/bin/sh", + "-c", + "while :; do sleep 6h && wait $${!}; nginx -s reload; done & nginx -g 'daemon off;'" + ] + + redis: + container_name: redis-dev + image: redis:7.2.5 + ports: + - 6379:6379 \ No newline at end of file diff --git a/src/main/java/com/umc/naoman/global/config/SwaggerConfig.java b/src/main/java/com/umc/naoman/global/config/SwaggerConfig.java index b441391..766b526 100644 --- a/src/main/java/com/umc/naoman/global/config/SwaggerConfig.java +++ b/src/main/java/com/umc/naoman/global/config/SwaggerConfig.java @@ -21,8 +21,8 @@ public OpenAPI openAPI() { .in(SecurityScheme.In.HEADER).name("Authorization"); SecurityRequirement securityRequirement = new SecurityRequirement().addList("bearerAuth"); -// Server server = new Server(); -// server.setUrl("http://{EC2_인스턴스의_IPv4_주소}"); + Server server = new Server(); + server.setUrl("http://52.79.212.19"); Server local = new Server(); local.setUrl("http://localhost:8080"); @@ -35,8 +35,8 @@ public OpenAPI openAPI() { private Info apiInfo() { return new Info() - .title("턴페이지 서비스 API") - .description("독후감 작성, 조회와 중고 도서 판매 등의 기능을 제공합니다.") + .title("나ㅇ만 서비스 API") + .description("친구, 가족, 동료와 찍은 사진들을 손쉽게 공유할 수 있도록 돕는 서비스, 나ㅇ만입니다.") .version("1.0.0"); } }