From fa9232725864c8fe7412335d7a24da5e8d30e0a3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=EC=9E=84=EC=84=B8=ED=9D=AC?= <109964874+Sehi55@users.noreply.github.com> Date: Sun, 17 May 2026 04:13:12 +0900 Subject: [PATCH 1/3] Feat/14 prod settings (#15) (#16) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * feat: actuator 의존성 추가 * feat: ci-prod 구현 --- .github/workflows/ci-prod.yml | 59 +++++++++++++++++++++++++ build.gradle | 3 ++ src/main/resources/application-prod.yml | 30 +++++++++++++ src/main/resources/application.yml | 20 ++++----- 4 files changed, 102 insertions(+), 10 deletions(-) create mode 100644 .github/workflows/ci-prod.yml create mode 100644 src/main/resources/application-prod.yml diff --git a/.github/workflows/ci-prod.yml b/.github/workflows/ci-prod.yml new file mode 100644 index 0000000..7495af5 --- /dev/null +++ b/.github/workflows/ci-prod.yml @@ -0,0 +1,59 @@ +# .github/workflows/ci-prod.yml +name: CI-PROD + +on: + pull_request: + branches: [main] + push: + branches: [main] + +permissions: + contents: read + id-token: write + +jobs: + build: + runs-on: ubuntu-latest + + steps: + - name: Checkout + uses: actions/checkout@v4 + + - name: Set up JDK 21 + uses: actions/setup-java@v4 + with: + distribution: temurin + java-version: "21" + + - name: Set up Gradle + uses: gradle/actions/setup-gradle@v4 + + - name: Grant execute permission for gradlew + run: chmod +x ./gradlew + + - name: Run tests + run: ./gradlew test --no-daemon + + - name: Generate image tag + if: github.event_name == 'push' + run: echo "IMAGE_TAG=$(git rev-parse --short HEAD)" >> $GITHUB_ENV + + - name: Configure AWS credentials (OIDC) + uses: aws-actions/configure-aws-credentials@v4 + with: + role-to-assume: ${{ secrets.AWS_ROLE_ARN }} + aws-region: ${{ vars.AWS_REGION }} + + - name: Login to Amazon ECR + if: github.event_name == 'push' + uses: aws-actions/amazon-ecr-login@v2 + + - name: Build Docker image + if: github.event_name == 'push' + run: | + docker build -t ${{ vars.ECR_REGISTRY }}/${{ vars.ECR_REPOSITORY }}:${{ env.IMAGE_TAG }} . + + - name: Push Docker image to ECR + if: github.event_name == 'push' + run: | + docker push ${{ vars.ECR_REGISTRY }}/${{ vars.ECR_REPOSITORY }}:${{ env.IMAGE_TAG }} \ No newline at end of file diff --git a/build.gradle b/build.gradle index 096a4ae..2276c72 100644 --- a/build.gradle +++ b/build.gradle @@ -37,6 +37,9 @@ dependencies { testImplementation 'io.projectreactor:reactor-test' testImplementation 'org.springframework.security:spring-security-test' testRuntimeOnly 'org.junit.platform:junit-platform-launcher' + + implementation 'org.springframework.boot:spring-boot-starter-actuator' + } dependencyManagement { diff --git a/src/main/resources/application-prod.yml b/src/main/resources/application-prod.yml new file mode 100644 index 0000000..163d7eb --- /dev/null +++ b/src/main/resources/application-prod.yml @@ -0,0 +1,30 @@ +server: + port: ${SERVER_PORT:19000} + +eureka: + client: + enabled: ${EUREKA_ENABLED:true} + service-url: + defaultZone: http://${EUREKA_HOST}:${EUREKA_PORT}/eureka/ + instance: + prefer-ip-address: true + +spring: + cloud: + inetutils: + ignored-interfaces: + - "lo" + - "docker.*" + - "veth.*" + preferred-networks: + - "10.0" + use-only-site-local-interfaces: true + +management: + endpoints: + web: + exposure: + include: health,info,prometheus + endpoint: + health: + show-details: always diff --git a/src/main/resources/application.yml b/src/main/resources/application.yml index 1aa7568..447df5d 100644 --- a/src/main/resources/application.yml +++ b/src/main/resources/application.yml @@ -9,54 +9,54 @@ spring: webflux: routes: - id: user-service - uri: lb://USER-SERVICE + uri: lb://user-service predicates: - Path=/api/v1/users/**,/api/v1/admin/users/**,/api/v1/auth/**,/api/v1/admin/auth/** - id: timeslot-service - uri: lb://TIMESLOT-SERVICE + uri: lb://timeslot-service predicates: - Path=/api/v1/restaurants/*/time-slots/**,/api/v1/admin/restaurants/*/time-slots/** - id: restaurant-service - uri: lb://RESTAURANT-SERVICE + uri: lb://restaurant-service predicates: - Path=/api/v1/restaurants/**,/api/v1/admin/restaurants/** - id: reservation-service - uri: lb://RESERVATION-SERVICE + uri: lb://reservation-service predicates: - Path=/api/v1/reservations/**,/api/v1/admin/reservations/** - id: catalog-service - uri: lb://CATALOG-SERVICE + uri: lb://catalog-service predicates: - Path=/api/v1/products/** - Method=GET - id: inventory-service - uri: lb://INVENTORY-SERVICE + uri: lb://inventory-service predicates: - Path=/api/v1/products/**,/api/v1/admin/products/** - Method=POST,PUT,PATCH,DELETE - id: order-service - uri: lb://ORDER-SERVICE + uri: lb://order-service predicates: - Path=/api/v1/orders/**,/api/v1/admin/orders/** - id: waiting-service - uri: lb://WAITING-SERVICE + uri: lb://waiting-service predicates: - Path=/api/v1/waitings/**,/api/v1/admin/waitings/** - id: notification-service - uri: lb://NOTIFICATION-SERVICE + uri: lb://notification-service predicates: - Path=/api/v1/notifications/**,/api/v1/admin/notifications/** - id: payment-service - uri: lb://PAYMENT-SERVICE + uri: lb://payment-service predicates: - Path=/api/v1/payments/**,/api/v1/admin/payments/** From 225537ec5bdada5dc5d68bdb872ff43ac05404ec Mon Sep 17 00:00:00 2001 From: Sehi55 Date: Sun, 17 May 2026 05:42:14 +0900 Subject: [PATCH 2/3] =?UTF-8?q?feat:=20cd-prod=20=EA=B5=AC=ED=98=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .github/workflows/cd-prod.yml | 121 ++++++++++++++++++++++++++++++++++ .github/workflows/ci.yml | 2 +- 2 files changed, 122 insertions(+), 1 deletion(-) create mode 100644 .github/workflows/cd-prod.yml diff --git a/.github/workflows/cd-prod.yml b/.github/workflows/cd-prod.yml new file mode 100644 index 0000000..e6434c3 --- /dev/null +++ b/.github/workflows/cd-prod.yml @@ -0,0 +1,121 @@ +name: CD-PROD + +on: + workflow_run: + workflows: ["CI-PROD"] + types: [completed] + workflow_dispatch: + +concurrency: + group: cd-prod + cancel-in-progress: false + +permissions: + contents: read + id-token: write + +env: + AWS_REGION: ${{ vars.AWS_REGION }} + ECR_REGISTRY: ${{ vars.ECR_REGISTRY }} + ECR_REPOSITORY: ${{ vars.ECR_REPOSITORY }} + ECS_CLUSTER: ${{ vars.ECS_CLUSTER }} + ECS_SERVICE: ${{ vars.ECS_SERVICE }} + TASK_FAMILY: ${{ vars.TASK_FAMILY }} + CONTAINER_NAME: ${{ vars.CONTAINER_NAME }} + +jobs: + deploy: + if: > + github.event_name == 'workflow_dispatch' || + (github.event_name == 'workflow_run' && github.event.workflow_run.conclusion == 'success') + runs-on: ubuntu-latest + timeout-minutes: 20 + + steps: + - name: Configure AWS credentials (OIDC) + uses: aws-actions/configure-aws-credentials@v4 + with: + role-to-assume: ${{ secrets.AWS_ROLE_ARN }} + aws-region: ${{ env.AWS_REGION }} + + - name: Resolve image tag + id: tag + run: | + if [ "${{ github.event_name }}" = "workflow_run" ]; then + IMAGE_TAG="${{ github.event.workflow_run.head_sha }}" + else + IMAGE_TAG="${{ github.sha }}" + fi + IMAGE_TAG="${IMAGE_TAG:0:7}" + echo "image_tag=${IMAGE_TAG}" >> "$GITHUB_OUTPUT" + + - name: Verify image exists in ECR + run: | + aws ecr describe-images \ + --repository-name "${ECR_REPOSITORY}" \ + --image-ids imageTag="${{ steps.tag.outputs.image_tag }}" \ + > /dev/null + + - name: Get current task definition + run: | + aws ecs describe-task-definition \ + --task-definition "${TASK_FAMILY}" \ + --query 'taskDefinition' > taskdef.json + + - name: Render new task definition + env: + IMAGE_URI: ${{ env.ECR_REGISTRY }}/${{ env.ECR_REPOSITORY }}:${{ steps.tag.outputs.image_tag }} + run: | + jq \ + --arg CN "${CONTAINER_NAME}" \ + --arg IMG "${IMAGE_URI}" \ + --arg SPRING_PROFILES_ACTIVE "prod" \ + --arg SERVER_PORT "19000" \ + --arg EUREKA_ENABLED "${{ vars.EUREKA_ENABLED }}" \ + --arg EUREKA_HOST "${{ vars.EUREKA_HOST }}" \ + --arg EUREKA_PORT "${{ vars.EUREKA_PORT }}" \ + --arg JWT_SECRET "${{ secrets.JWT_SECRET }}" \ + ' + .containerDefinitions |= map( + if .name == $CN then + .image = $IMG + | .environment = [ + {"name":"SPRING_PROFILES_ACTIVE","value":$SPRING_PROFILES_ACTIVE}, + {"name":"SERVER_PORT","value":$SERVER_PORT}, + {"name":"EUREKA_ENABLED","value":$EUREKA_ENABLED}, + {"name":"EUREKA_HOST","value":$EUREKA_HOST}, + {"name":"EUREKA_PORT","value":$EUREKA_PORT}, + {"name":"JWT_SECRET","value":$JWT_SECRET} + ] + else . + end + ) + | del( + .taskDefinitionArn, .revision, .status, + .requiresAttributes, .compatibilities, + .registeredAt, .registeredBy + ) + ' taskdef.json > taskdef.new.json + + - name: Register new task definition revision + id: register + run: | + ARN=$(aws ecs register-task-definition \ + --cli-input-json file://taskdef.new.json \ + --query 'taskDefinition.taskDefinitionArn' \ + --output text) + echo "task_def_arn=${ARN}" >> "$GITHUB_OUTPUT" + + - name: Deploy to ECS service + run: | + aws ecs update-service \ + --cluster "${ECS_CLUSTER}" \ + --service "${ECS_SERVICE}" \ + --task-definition "${{ steps.register.outputs.task_def_arn }}" \ + --force-new-deployment + + - name: Wait for stable + run: | + aws ecs wait services-stable \ + --cluster "${ECS_CLUSTER}" \ + --services "${ECS_SERVICE}" diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 17c4374..025ddd7 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -2,7 +2,7 @@ name: Java CI with Gradle on: pull_request: - branches: [ "dev", "main" ] + branches: [ "dev"] jobs: build: From 9f19de0fbd9acff175a4f07535161e0d1ad78bdc Mon Sep 17 00:00:00 2001 From: Sehi55 Date: Sun, 17 May 2026 06:43:35 +0900 Subject: [PATCH 3/3] =?UTF-8?q?fix:=20api=20=EA=B6=8C=ED=95=9C=EB=AC=B8?= =?UTF-8?q?=EC=A0=9C=20=EB=95=8C=EB=AC=B8=EC=97=90=20=ED=97=AC=EC=8A=A4?= =?UTF-8?q?=EC=B2=B4=ED=81=AC=20=EC=8B=A4=ED=8C=A8=20=EC=98=A4=EB=A5=98?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../michelet/gateway/infrastructure/config/SecurityConfig.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/java/com/michelet/gateway/infrastructure/config/SecurityConfig.java b/src/main/java/com/michelet/gateway/infrastructure/config/SecurityConfig.java index effc513..171c598 100644 --- a/src/main/java/com/michelet/gateway/infrastructure/config/SecurityConfig.java +++ b/src/main/java/com/michelet/gateway/infrastructure/config/SecurityConfig.java @@ -28,7 +28,7 @@ public SecurityWebFilterChain securityWebFilterChain(ServerHttpSecurity http, Ga exchanges-> exchanges.pathMatchers( "/api/*/auth/login", "/api/*/auth/reissue", - "/api/*/users/signup" + "/api/*/users/signup", "/actuator/health", "/actuator/info" ).permitAll() .pathMatchers("/api/*/admin/**").hasRole("MASTER") .anyExchange().authenticated()