From 24e6d50badee040d6b5956af10a3b1344fa19edb Mon Sep 17 00:00:00 2001 From: hwangdaesun Date: Tue, 16 Jul 2024 15:59:18 +0900 Subject: [PATCH 1/3] =?UTF-8?q?refactor/#383=20:=20version=20=EC=88=98?= =?UTF-8?q?=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- BE/exceed/build.gradle | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/BE/exceed/build.gradle b/BE/exceed/build.gradle index 0f6067f32..22d38b723 100644 --- a/BE/exceed/build.gradle +++ b/BE/exceed/build.gradle @@ -16,7 +16,7 @@ plugins { } group = 'com.gaebaljip' -version = '0.0.1-SNAPSHOT' +version = '1.0.0' java { sourceCompatibility = '17' From bbd580e9b06647331ba8110f66da555f77adb6a1 Mon Sep 17 00:00:00 2001 From: hwangdaesun Date: Tue, 16 Jul 2024 16:04:41 +0900 Subject: [PATCH 2/3] =?UTF-8?q?feat/#383=20:=20prod=20workflow=20=EC=83=9D?= =?UTF-8?q?=EC=84=B1=20=EB=B0=8F=20=EA=B8=B0=EC=A1=B4=20workflow=20?= =?UTF-8?q?=EC=9D=B4=EB=A6=84=20=EB=B3=80=EA=B2=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../workflows/devWorkflow.yml | 0 .github/workflows/prodWorkflow.yml | 109 ++++++++++++++++++ 2 files changed, 109 insertions(+) rename ".github/workflows/\btestAndDeploy.yml" => .github/workflows/devWorkflow.yml (100%) create mode 100644 .github/workflows/prodWorkflow.yml diff --git "a/.github/workflows/\btestAndDeploy.yml" b/.github/workflows/devWorkflow.yml similarity index 100% rename from ".github/workflows/\btestAndDeploy.yml" rename to .github/workflows/devWorkflow.yml diff --git a/.github/workflows/prodWorkflow.yml b/.github/workflows/prodWorkflow.yml new file mode 100644 index 000000000..73d5201c5 --- /dev/null +++ b/.github/workflows/prodWorkflow.yml @@ -0,0 +1,109 @@ +name: testAndDeploy + +on: + pull_request: + branches: + - release + - main + types: + - closed + +defaults: + run: + working-directory: ./BE/exceed + +jobs: + build: + runs-on: ubuntu-22.04 + permissions: + contents: read + pull-requests: write + + steps: + - uses: actions/checkout@v3 + - name: Set up JDK 17 + uses: actions/setup-java@v3 + with: + java-version: '17' + distribution: 'temurin' + + - name: Grant execute permission for gradlew + run: chmod +x gradlew + + - 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- + + - name: Build with Gradle Wrapper + run: ./gradlew build + + - name: Jacoco Report to PR + id: jacoco + uses: madrapps/jacoco-report@v1.6.1 + with: + paths: ${{ github.workspace }}/**/build/reports/jacoco/test/jacocoTestReport.xml + token: ${{ secrets.GITHUB_TOKEN }} + + - name: Send docker-compose.yml + uses: appleboy/scp-action@master + with: + host: ${{ secrets.SSH_HOST }} + username: ${{ secrets.SSH_USERNAME }} + key: ${{ secrets.SSH_KEY }} + source: ./BE/exceed/docker-compose-prod.yml + target: /home/ubuntu/backend-deploy + + - name: Send resources-develop-environment + uses: appleboy/scp-action@master + with: + host: ${{ secrets.SSH_HOST }} + username: ${{ secrets.SSH_USERNAME }} + key: ${{ secrets.SSH_KEY }} + source: ./BE/exceed/resources/gaebaljip-prod-environment + target: /home/ubuntu/backend-deploy + + - name: Create .env.prod file + run: | + echo "${{ secrets.ENV_PROD_VARS }}" > .env.prod + + - name: Send env file + uses: appleboy/scp-action@master + with: + host: ${{ secrets.SSH_HOST }} + username: ${{ secrets.SSH_USERNAME }} + key: ${{ secrets.SSH_KEY }} + source: ./BE/exceed/.env.prod + target: /home/ubuntu/backend-deploy + + - name: Docker Image Build + run: docker build -f Dockerfile-prod -t ${{ secrets.DOCKER_HUB_USER_NAME }}/gaebaljip-prod:latest . + + - name: Docker Hub Login + uses: docker/login-action@v2 + with: + username: ${{ secrets.DOCKER_HUB_USER_NAME }} + password: ${{ secrets.DOCKER_HUB_TOKEN }} + + - name: docker Hub Push + run: docker push ${{ secrets.DOCKER_HUB_USER_NAME }}/gaebaljip-prod:latest + + - name: SSH Deploy + uses: appleboy/ssh-action@v1.0.3 + with: + host: ${{ secrets.SSH_HOST }} + username: ${{ secrets.SSH_USERNAME }} + key: ${{ secrets.SSH_KEY }} + script: | + cd backend-deploy/BE/exceed + sudo docker-compose down + sudo docker pull ${{ secrets.DOCKER_HUB_USER_NAME }}/gaebaljip-prod:latest + sudo docker-compose up --build -d + sudo docker image prune -a -f + + From 9808bc9540487e122ebcf6bff483bc26bef3a6a3 Mon Sep 17 00:00:00 2001 From: hwangdaesun Date: Tue, 16 Jul 2024 16:07:49 +0900 Subject: [PATCH 3/3] =?UTF-8?q?feat/#383=20:=20prod=EC=9A=A9=20=EC=83=9D?= =?UTF-8?q?=EC=84=B1?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- BE/exceed/.gitignore | 3 +- BE/exceed/Dockerfile | 2 +- BE/exceed/Dockerfile-prod | 18 +++++ BE/exceed/docker-compose-prod.yml | 76 +++++++++++++++++++ .../prometheus/config/prometheus.yml | 19 +++++ .../common/data/MariaDBAutoComplete.java | 2 + .../src/main/resources/application-prod.yml | 73 +++++++++++++++++- 7 files changed, 186 insertions(+), 7 deletions(-) create mode 100644 BE/exceed/Dockerfile-prod create mode 100644 BE/exceed/docker-compose-prod.yml create mode 100644 BE/exceed/resources/gaebaljip-prod-environment/prometheus/config/prometheus.yml diff --git a/BE/exceed/.gitignore b/BE/exceed/.gitignore index 4130e6a2f..6e25862c2 100644 --- a/BE/exceed/.gitignore +++ b/BE/exceed/.gitignore @@ -45,8 +45,7 @@ src/main/resources/static/docs/api-doc.html ### env .env -env-dev - +.env.prod ### jmh diff --git a/BE/exceed/Dockerfile b/BE/exceed/Dockerfile index 283369bfa..36709bd15 100644 --- a/BE/exceed/Dockerfile +++ b/BE/exceed/Dockerfile @@ -15,4 +15,4 @@ COPY ./food_data.csv ./food_data.csv EXPOSE 8080 # CMD 명령어에서 CSV 파일의 위치를 절대 경로로 지정 -CMD ["java", "-jar", "-Dspring.profiles.active=dev", "eatceed.jar", "./food_data.csv"] +CMD ["java", "-jar", "-Dspring.profiles.active=dev", "eatceed.jar", "./food_data.csv"] \ No newline at end of file diff --git a/BE/exceed/Dockerfile-prod b/BE/exceed/Dockerfile-prod new file mode 100644 index 000000000..56bc574fe --- /dev/null +++ b/BE/exceed/Dockerfile-prod @@ -0,0 +1,18 @@ +FROM openjdk:17-oracle + +ENV TZ=Asia/Seoul + +# 앱을 위한 작업 디렉토리 설정 +WORKDIR /app + +# JAR 파일 복사 +ARG JAR_FILE="./build/libs/*.jar" +COPY ${JAR_FILE} eatceed.jar + +# CSV 파일 복사 +COPY ./food_data.csv ./food_data.csv + +EXPOSE 8080 + +# CMD 명령어에서 CSV 파일의 위치를 절대 경로로 지정 +CMD ["java", "-jar", "-Dspring.profiles.active=prod", "eatceed.jar", "./food_data.csv"] \ No newline at end of file diff --git a/BE/exceed/docker-compose-prod.yml b/BE/exceed/docker-compose-prod.yml new file mode 100644 index 000000000..f6827f655 --- /dev/null +++ b/BE/exceed/docker-compose-prod.yml @@ -0,0 +1,76 @@ +version: '3' +services: + eatceed-redis: + image: redis:alpine + container_name: gaebaljip-redis + command: redis-server --port 6379 + expose: + - "6379" + networks: + - gaebaljip-network + + eatceed-backend: + image: hwangdaesun/gaebaljip-prod:latest + container_name: gaebaljip-spring + ports: + - 8080:8080 + depends_on: + - eatceed-redis + environment: + - RDS_DATABASE_ENDPOINT=${RDS_DATABASE_ENDPOINT} + - RDS_PORT=${RDS_PORT} + - RDS_DB_NAME=${RDS_DB_NAME} + - RDS_DATABASE_USERNAME=${RDS_DATABASE_USERNAME} + - RDS_DATABASE_PASSWORD=${RDS_DATABASE_PASSWORD} + - S3_BUCKET_NAME=${S3_BUCKET_NAME} + - CLOUD_AWS_ACCESS_KEY=${CLOUD_AWS_ACCESS_KEY} + - CLOUD_AWS_SECRET_KEY=${CLOUD_AWS_SECRET_KEY} + - JWT_SECRET=${JWT_SECRET} + - SES_MAIL_ADDRESS=${SES_MAIL_ADDRESS} + - ENCRYPTION_SPEC=${ENCRYPTION_SPEC} + - ENCRYPTION_SECRET=${ENCRYPTION_SECRET} + - ENCRYPTION_ALGORITHM=${ENCRYPTION_ALGORITHM} + - SPRING_REDIS_HOST=gaebaljip-redis + - SPRING_REDIS_PORT=6379 + networks: + - gaebaljip-network + restart: "always" + + grafana: + image: grafana/grafana:latest + container_name: grafana + restart: "always" + ports: + - "3000:3000" + volumes: + - grafana-data:/var/lib/grafana + - ./resources/gaebaljip-prod-environment/grafana/provisioning/:/etc/grafana/provisioning/ + environment: + - GF_SERVER_ROOT_URL=localhost:3000 + - GF_SECURITY_ADMIN_PASSWORD=${GRAFANA_PASSWORD} + depends_on: + - prometheus + networks: + - gaebaljip-network + + prometheus: + image: prom/prometheus:latest + container_name: prometheus + restart: "always" + ports: + - "9090:9090" + volumes: + - ./resources/gaebaljip-prod-environment/prometheus/config:/etc/prometheus/ + - prometheus-data:/prometheus + command: + - '--config.file=/etc/prometheus/prometheus.yml' + - '--storage.tsdb.path=/prometheus' + networks: + - gaebaljip-network + +volumes: + grafana-data: + prometheus-data: + +networks: + gaebaljip-network: \ No newline at end of file diff --git a/BE/exceed/resources/gaebaljip-prod-environment/prometheus/config/prometheus.yml b/BE/exceed/resources/gaebaljip-prod-environment/prometheus/config/prometheus.yml new file mode 100644 index 000000000..554374bd7 --- /dev/null +++ b/BE/exceed/resources/gaebaljip-prod-environment/prometheus/config/prometheus.yml @@ -0,0 +1,19 @@ +global: + scrape_interval: 15s + evaluation_interval: 15s +alerting: + alertmanagers: + - static_configs: + - targets: + # - alertmanager:9093 +rule_files: +scrape_configs: + - job_name: "prometheus" + static_configs: + - targets: ["localhost:9090"] + #추가 + - job_name: "spring-actuator" + metrics_path: '/actuator/prometheus' + scrape_interval: 1s + static_configs: + - targets: ['3.37.117.77:8080'] \ No newline at end of file diff --git a/BE/exceed/src/main/java/com/gaebaljip/exceed/common/data/MariaDBAutoComplete.java b/BE/exceed/src/main/java/com/gaebaljip/exceed/common/data/MariaDBAutoComplete.java index c73563ad1..ab26661b2 100644 --- a/BE/exceed/src/main/java/com/gaebaljip/exceed/common/data/MariaDBAutoComplete.java +++ b/BE/exceed/src/main/java/com/gaebaljip/exceed/common/data/MariaDBAutoComplete.java @@ -7,6 +7,7 @@ import org.springframework.boot.ApplicationArguments; import org.springframework.boot.ApplicationRunner; import org.springframework.boot.autoconfigure.condition.ConditionalOnExpression; +import org.springframework.context.annotation.Profile; import org.springframework.stereotype.Component; import com.gaebaljip.exceed.adapter.out.jpa.food.FoodEntity; @@ -22,6 +23,7 @@ @Log4j2 @RequiredArgsConstructor @ConditionalOnExpression("${ableAutoComplete:true}") +@Profile("!prod") public class MariaDBAutoComplete implements ApplicationRunner { private final FoodPort foodPort; diff --git a/BE/exceed/src/main/resources/application-prod.yml b/BE/exceed/src/main/resources/application-prod.yml index 03adbb690..0ac6b99f8 100644 --- a/BE/exceed/src/main/resources/application-prod.yml +++ b/BE/exceed/src/main/resources/application-prod.yml @@ -4,14 +4,20 @@ spring: driver-class-name: org.mariadb.jdbc.Driver username: ${RDS_DATABASE_USERNAME} password: ${RDS_DATABASE_PASSWORD} + redis: + host: ${SPRING_REDIS_HOST} + port: ${SPRING_REDIS_PORT} jpa: hibernate: naming: physical-strategy: org.hibernate.boot.model.naming.PhysicalNamingStrategyStandardImpl dialect: org.hibernate.dialect.MariaDBDialect - ddl-auto: none - show-sql: true - defer-datasource-initialization: true + ddl-auto: validate + properties: + hibernate: + show_sql: true + format_sql: true + use_sql_comments: true cloud: aws: credentials: @@ -32,12 +38,71 @@ encryption: jwt: secret: ${JWT_SECRET} +exceed: + url : https://eatceed.net + +springdoc: + api-docs: + path: /api-docs # API 문서 생성 경로 + groups: + enabled: true + swagger-ui: + path: /index.html # Swagger-ui 경로 + enabled: true + groups-order: asc + tags-sorter: alpha + operations-sorter: alpha + display-request-duration: true + doc-expansion: none + cache: + disabled: true + override-with-generic-response: false + model-and-view-allowed: true + default-consumes-media-type: application/json + default-produces-media-type: application/json + ableAutoComplete: true +management: + endpoints: + web: + exposure: + include: "*" + exclude: "env, beans" + logging: level: org: hibernate: type: descriptor: - sql: trace \ No newline at end of file + sql: trace + +org: + quartz: + scheduler: + instanceName: gaebaljip + instanceId: AUTO + rmi: + export: false + proxy: false + threadPool: + class: org.quartz.simpl.SimpleThreadPool + threadCount: 5 + context: + key: + QuartzTopic: QuartzPorperties + jobStore: + class: org.quartz.impl.jdbcjobstore.JobStoreTX + driverDelegateClass: org.quartz.impl.jdbcjobstore.StdJDBCDelegate + tablePrefix: QRTZ_ + isClustered: true + dataSource: gaebaljip + dataSource: + gaebaljip: + provider: hikaricp + driver: org.mariadb.jdbc.Driver + URL: jdbc:mariadb://${RDS_DATABASE_ENDPOINT}:${RDS_PORT}/${RDS_DB_NAME}?serverTimezone=Asia/Seoul + user: ${RDS_DATABASE_USERNAME} + password: ${RDS_DATABASE_PASSWORD} + maxConnections: 30 \ No newline at end of file