Skip to content

chore/38 - ci 설정 - #39

Merged
ji-circle merged 3 commits into
devfrom
chore/38-inventory-cicd-prometheus
May 17, 2026
Merged

chore/38 - ci 설정#39
ji-circle merged 3 commits into
devfrom
chore/38-inventory-cicd-prometheus

Conversation

@ji-circle

@ji-circle ji-circle commented May 17, 2026

Copy link
Copy Markdown
Contributor

📝 작업 내용

이번 PR에서 작업한 내용을 설명해주세요.

  • 일단 ci만 연결

🚀 주요 변경 사항

완료한 이슈 번호
Close #
관련된 이슈 번호 (닫고 싶지 않은 경우)
Related to #

✅ 자체 체크리스트 (필수)

  • ./gradlew build 실행 결과 정상 (인증샷 첨부)
  • 팀 내 컨벤션 준수 및 불필요한 로그, import 제거
  • 중요한 변경 사항이 팀에 공유되었는지

📸 테스트 인증샷

빌드 결과 및 IntelliJ HTTP Client 실행 화면을 여기에 첨부해 주세요.

💬 리뷰어 전달사항 (선택)

특별히 봐주었으면 하는 부분이나 논의가 필요한 점을 적어주세요.



📎 참고 자료

관련 문서, 레퍼런스 링크 등이 있다면 여기에 첨부해주세요.

Summary by CodeRabbit

릴리스 노트

  • New Features

    • Prometheus 기반 애플리케이션 메트릭 모니터링 기능 추가
  • Chores

    • CI/CD 파이프라인 추가로 자동화된 테스트 및 Docker 이미지 빌드/배포 구현
    • 멀티스테이지 Docker 빌드로 최적화하여 이미지 크기 감소
    • 프로덕션 환경 설정 추가 (데이터베이스, Redis, Kafka 등)

Review Change Stack

@ji-circle ji-circle added this to the 8. 기타 milestone May 17, 2026
@ji-circle ji-circle added the enhancement New feature or request label May 17, 2026
@coderabbitai

coderabbitai Bot commented May 17, 2026

Copy link
Copy Markdown

Warning

Rate limit exceeded

@ji-circle has exceeded the limit for the number of commits that can be reviewed per hour. Please wait 47 minutes and 31 seconds before requesting another review.

You’ve run out of usage credits. Purchase more in the billing tab.

⌛ How to resolve this issue?

After the wait time has elapsed, a review can be triggered using the @coderabbitai review command as a PR comment. Alternatively, push new commits to this PR.

We recommend that you space out your commits to avoid hitting the rate limit.

🚦 How do rate limits work?

CodeRabbit enforces hourly rate limits for each developer per organization.

Our paid plans have higher rate limits than the trial, open-source and free plans. In all cases, we re-allow further reviews after a brief timeout.

Please see our FAQ for further information.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro Plus

Run ID: 8814b72e-5357-408a-8a0b-35e48a557cdf

📥 Commits

Reviewing files that changed from the base of the PR and between 9ab9b99 and 9254651.

📒 Files selected for processing (2)
  • build.gradle
  • src/test/java/com/michelet/inventory/application/StockSchedulerServiceTest.java
📝 Walkthrough

개요

프로덕션 환경 배포를 위한 통합 인프라를 구축합니다. GitHub Actions CI/CD 워크플로우를 추가하여 테스트 자동화와 ECR 이미지 배포를 구현하고, Dockerfile을 멀티스테이지 빌드로 전환하며, Spring Boot 프로덕션 설정과 Prometheus 모니터링을 설정합니다.

변경사항

프로덕션 배포 인프라

계층 / 파일 요약
빌드 설정 및 의존성
build.gradle
Prometheus 메트릭 레지스트리(micrometer-registry-prometheus) 런타임 의존성을 추가하고, plain JAR 생성을 비활성화하여 Spring Boot 빌드 산출물을 bootJar만 생성하도록 구성합니다.
멀티스테이지 Docker 빌드
Dockerfile
JDK 17 기반 builder 단계에서 Gradle로 bootJar를 생성한 후, JRE 17 기반 런타임 단계로 전환하여 빌드 산출물을 app.jar로 복사합니다. SERVER_PORT 빌드 인자를 통해 노출 포트를 동적으로 설정합니다.
프로덕션 애플리케이션 설정
src/main/resources/application-prod.yml
PostgreSQL 데이터소스, Redis 캐시, Kafka 브로커/프로듀서/컨슈머, JPA/Hibernate 데이터베이스 관리, Eureka 서비스 등록, Actuator 엔드포인트(health, info, prometheus) 및 헬스 상세 표시를 구성합니다.
CI/CD 자동화 워크플로우
.github/workflows/ci-prod.yml
pull_request 및 push 이벤트에서 Gradle 테스트를 실행합니다. push 이벤트 시에만 AWS OIDC 인증으로 ECR 로그인 후, IMAGE_TAG(커밋 해시 앞 7자)와 SERVER_PORT 빌드 인자를 사용하여 Docker 이미지를 빌드하고 지정된 ECR 레지스트리로 푸시합니다.
빌드 아티팩트 관리
.gitignore
Gradle 래퍼 JAR 예외 규칙(!gradle/wrapper/gradle-wrapper.jar)을 build/ 섹션에서 Java 섹션으로 이동하고, Docker Compose 오버라이드 파일 패턴을 Docker 섹션에 추가합니다.

예상 코드 검토 시간

🎯 3 (중간 복잡도) | ⏱️ ~20분

관련 이슈

  • #38: 이 변경사항이 CI/CD 파이프라인(GitHub Actions + Docker/ECR) 및 Prometheus 모니터링(micrometer 의존성 + Actuator 엔드포인트 노출) 구현을 통해 해당 이슈의 목표를 직접 달성합니다.

관련된 PR

  • Miche-Let/inventory-service#7: Dockerfile의 컨테이너 빌드/실행 로직(JAR 복사 전략, 포트 처리) 리팩토링이 해당 PR의 컨테이너화 변경사항과 겹칩니다.

제안 검토자

  • githyj-jang
  • qldo
  • jihxonx
  • Sehi55

🐰 프로덕션의 길을 다지며,
Docker와 CI/CD로 빌드를 재단,
Prometheus는 흘러내리고,
Eureka는 등록되며,
ECR로 푸시하는 배포의 향연! 🚀

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 inconclusive)

Check name Status Explanation Resolution
Title check ❓ Inconclusive 제목은 CI 설정 추가라는 주요 변경사항을 나타내지만, 구체적이지 않고 'chore/38'이라는 브랜치 번호를 포함하여 다소 모호합니다. 제목을 'Add CI/CD workflow with Prometheus monitoring and Docker build'과 같이 더 구체적이고 설명적으로 수정하여 주요 변경사항(CI 워크플로우, Docker 멀티스테이지 빌드, Prometheus 모니터링)을 명확히 하세요.
✅ Passed checks (4 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch chore/38-inventory-cicd-prometheus

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 3

🧹 Nitpick comments (1)
.github/workflows/ci-prod.yml (1)

50-53: ⚡ Quick win

PR 이벤트에서도 Docker 이미지 빌드를 수행하고 있습니다.

현재는 pull_request에서도 이미지를 빌드해 CI 시간이 늘어납니다. 배포 파이프라인 목적이 push 경로라면 build 단계도 push로 제한하는 게 더 일관적입니다.

수정 예시
             -   name: Build Docker image  # 이미지 빌드해서
+                if: github.event_name == 'push'
                 run: |
                     docker build --build-arg SERVER_PORT=${{ vars.SERVER_PORT }} -t ${{ vars.ECR_REGISTRY }}/${{ vars.ECR_REPOSITORY }}:${{ env.IMAGE_TAG }} .
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In @.github/workflows/ci-prod.yml around lines 50 - 53, The Docker image build
is running for pull_request events causing unnecessary CI time; restrict the
build to push events by guarding the build step or job (the step named "Build
Docker image" that runs the docker build command) with an event check (e.g.,
only run when github.event_name == 'push' or move the step into a job that has a
push-only trigger) so the image build executes only on push/deploy paths; update
the workflow triggers/step condition accordingly and keep the existing docker
build arguments and tags unchanged.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@Dockerfile`:
- Around line 12-20: The Dockerfile runs the runtime container as root because
there is no USER instruction; update the Dockerfile to create and switch to a
non-root user before the ENTRYPOINT so the JVM process runs with least
privileges (e.g., add steps to create a group/user, chown /app to that user, and
add a USER <username> line placed before ENTRYPOINT); reference the existing
WORKDIR /app, the copied app.jar, and the ENTRYPOINT
["java","-jar","/app/app.jar"] so the new user owns /app and runs the jar.

In `@src/main/resources/application-prod.yml`:
- Around line 29-31: 현재 application-prod.yml의 jpa.hibernate.ddl-auto가 update로
설정되어 있어 프로덕션에서 스키마가 런타임에 변경될 수 있으니 값을 validate로 변경하세요; application-prod.yml 파일에서
jpa.hibernate.ddl-auto: update를 jpa.hibernate.ddl-auto: validate로 바꾸고, 데이터베이스
스키마 변경은 Flyway/ Liquibase 같은 명시적 마이그레이션 도구로 관리하도록 관련 배포 문서나 CI/CD 파이프라인을 업데이트하여
프로덕션과 Docker 환경이 동일한 검증 방식을 사용하도록 보장하세요.
- Line 36: Change the production YAML to stop logging SQL and exposing health
details: set show-sql to false (replace the current show-sql: true) and add or
update the management.endpoint.health.show-details property to a restrictive
value like never (or when-authorized) so health endpoint details are not exposed
publicly; target the settings shown as show-sql and
management.endpoint.health.show-details in application-prod.yml.

---

Nitpick comments:
In @.github/workflows/ci-prod.yml:
- Around line 50-53: The Docker image build is running for pull_request events
causing unnecessary CI time; restrict the build to push events by guarding the
build step or job (the step named "Build Docker image" that runs the docker
build command) with an event check (e.g., only run when github.event_name ==
'push' or move the step into a job that has a push-only trigger) so the image
build executes only on push/deploy paths; update the workflow triggers/step
condition accordingly and keep the existing docker build arguments and tags
unchanged.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro Plus

Run ID: 3a5710b2-ec5d-4791-b249-a8a418fec3c6

📥 Commits

Reviewing files that changed from the base of the PR and between 081faf3 and 9ab9b99.

⛔ Files ignored due to path filters (1)
  • gradle/wrapper/gradle-wrapper.jar is excluded by !**/*.jar
📒 Files selected for processing (5)
  • .github/workflows/ci-prod.yml
  • .gitignore
  • Dockerfile
  • build.gradle
  • src/main/resources/application-prod.yml

Comment thread Dockerfile
Comment on lines +29 to +31
jpa:
hibernate:
ddl-auto: update

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟠 Major | ⚡ Quick win

🧩 Analysis chain

🏁 Script executed:

# application-prod.yml 파일이 존재하는지 확인하고 내용 읽기
if [ -f "src/main/resources/application-prod.yml" ]; then
  echo "=== application-prod.yml 파일 내용 ===" 
  cat -n "src/main/resources/application-prod.yml"
else
  echo "파일을 찾을 수 없습니다."
  # 유사한 파일들 찾아보기
  echo "=== 유사한 설정 파일 찾기 ==="
  find . -name "application*.yml" -o -name "application*.yaml" 2>/dev/null | head -20
fi

Repository: Miche-Let/inventory-service

Length of output: 2188


🏁 Script executed:

# 프로젝트 구조 확인
echo "=== 프로젝트 구조 확인 ===" 
ls -la src/main/resources/ 2>/dev/null || echo "resources 디렉토리 없음"

Repository: Miche-Let/inventory-service

Length of output: 550


🏁 Script executed:

# 다른 환경 파일들의 ddl-auto 설정 확인
echo "=== application-docker.yml 중 ddl-auto 설정 ===" 
grep -A 2 "ddl-auto" src/main/resources/application-docker.yml 2>/dev/null || echo "설정 없음"

echo -e "\n=== application-local.yml 중 ddl-auto 설정 ===" 
grep -A 2 "ddl-auto" src/main/resources/application-local.yml 2>/dev/null || echo "설정 없음"

echo -e "\n=== application-perf.yml 중 ddl-auto 설정 ===" 
grep -A 2 "ddl-auto" src/main/resources/application-perf.yml 2>/dev/null || echo "설정 없음"

echo -e "\n=== application.yml 중 ddl-auto 설정 ===" 
grep -A 2 "ddl-auto" src/main/resources/application.yml 2>/dev/null || echo "설정 없음"

Repository: Miche-Let/inventory-service

Length of output: 366


🏁 Script executed:

# Hibernate 프로젝트 설정에서 JPA/Hibernate 버전 확인
echo "=== Maven/Gradle 설정에서 Hibernate 버전 확인 ===" 
if [ -f "pom.xml" ]; then
  grep -i "hibernate\|spring-data-jpa\|spring-boot" pom.xml | head -20
elif [ -f "build.gradle" ] || [ -f "build.gradle.kts" ]; then
  grep -i "hibernate\|spring-data-jpa\|spring-boot" build.gradle* | head -20
fi

Repository: Miche-Let/inventory-service

Length of output: 795


프로덕션 환경에서 ddl-auto: update 설정을 validate로 변경해야 합니다.

런타임에 자동으로 스키마를 변경하면 예기치 않은 드리프트와 장애가 발생할 수 있습니다. Docker 환경에서는 이미 validate를 사용 중이므로, 프로덕션도 동일하게 설정하고 명시적 마이그레이션으로 관리하는 것이 안전합니다.

수정 예시
     jpa:
         hibernate:
-            ddl-auto: update
+            ddl-auto: validate
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
jpa:
hibernate:
ddl-auto: update
jpa:
hibernate:
ddl-auto: validate
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@src/main/resources/application-prod.yml` around lines 29 - 31, 현재
application-prod.yml의 jpa.hibernate.ddl-auto가 update로 설정되어 있어 프로덕션에서 스키마가 런타임에
변경될 수 있으니 값을 validate로 변경하세요; application-prod.yml 파일에서 jpa.hibernate.ddl-auto:
update를 jpa.hibernate.ddl-auto: validate로 바꾸고, 데이터베이스 스키마 변경은 Flyway/ Liquibase
같은 명시적 마이그레이션 도구로 관리하도록 관련 배포 문서나 CI/CD 파이프라인을 업데이트하여 프로덕션과 Docker 환경이 동일한 검증
방식을 사용하도록 보장하세요.

hibernate:
default_schema: inventory_service
format_sql: true
show-sql: true

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟠 Major | ⚡ Quick win

🧩 Analysis chain

🏁 Script executed:

find . -name "application-prod.yml" -type f

Repository: Miche-Let/inventory-service

Length of output: 113


🏁 Script executed:

cat -n ./src/main/resources/application-prod.yml

Repository: Miche-Let/inventory-service

Length of output: 2153


🌐 Web query:

Spring Boot show-sql production security best practice

💡 Result:

In production environments, you should always set spring.jpa.show-sql=false [1][2]. Enabling this property is considered a security and operational anti-pattern for several reasons [3][2][4]. Why spring.jpa.show-sql is not suitable for production: 1. Security Risk: It can inadvertently expose sensitive data, database schema details, or internal logic in your application logs [2]. 2. Performance Impact: It writes directly to standard output (System.out) without the optimizations, filtering, or asynchronous handling provided by professional logging frameworks [3][5][4]. This can cause significant performance degradation under heavy load [2]. 3. Log Noise: It generates excessive, unformatted output that fills up log files rapidly, making it difficult to identify actual application errors or security incidents [2][4]. 4. Limited Utility: It only displays the prepared statement structure (with question marks for parameters), which is often insufficient for debugging complex issues [2]. Recommended Best Practices: If you need to inspect SQL queries for troubleshooting, use the following approaches instead of show-sql: 1. Use Logging Frameworks: Configure your logging framework (e.g., Logback) to capture SQL at the appropriate level. This allows you to route logs to files, filter them, and manage them according to your organization's retention policies [5][4]. - To log SQL statements: Set logging.level.org.hibernate.SQL=DEBUG [5][6][4]. - To log parameter values: Set logging.level.org.hibernate.type.descriptor.sql.BasicBinder=TRACE [5][2][6][4]. 2. Use Spring Profiles: Always restrict these logging configurations to non-production profiles (e.g., dev or test) using Spring Profiles [2]. Ensure your production configuration explicitly disables them [1]. 3. Use Interceptors (Advanced): For more robust or customized logging, consider using a library like DataSource-Proxy [3][5]. This allows you to intercept JDBC calls, format them, and log them consistently without relying on Hibernate-specific properties [3][5]. Security Note: While logging SQL is a debugging tool, it is not a substitute for proper security measures. Always protect against SQL injection by using parameterized queries (which Spring Data JPA does automatically when using standard repository methods or @Query with named/indexed parameters) and avoiding manual string concatenation in queries [7][8][9].

Citations:


🌐 Web query:

Spring Boot management.endpoint.health.show-details production security best practice

💡 Result:

In production environments, setting management.endpoint.health.show-details to always is generally considered a security risk and is not recommended [1][2][3]. The health endpoint is often exposed to monitoring systems (like Kubernetes liveness/readiness probes) that may not be authenticated [1][4][5]. If show-details is set to always, the endpoint may reveal sensitive internal information—such as database connection details, disk space paths, or other infrastructure-specific data—to anyone who can access the endpoint [1][3][4]. Best Practices for Production: 1. Use when-authorized: Instead of always, set management.endpoint.health.show-details to when-authorized [1][2]. This ensures that detailed health information is only visible to authenticated users with appropriate roles, while unauthenticated users (or monitoring tools) receive only the basic status [1][2]. 2. Configure Roles: When using when-authorized, you can define which roles are permitted to see the details using the management.endpoint.health.roles property [1][2]. 3. Secure Actuator Endpoints: Always protect your Actuator endpoints using Spring Security [6][7]. If you must expose the health endpoint for monitoring, ensure your security configuration explicitly permits access to the basic health status for those monitoring tools while restricting access to the detailed information [1][2][6]. 4. Limit Exposure: Only expose the endpoints you absolutely need [6][7]. Use management.endpoints.web.exposure.include to explicitly list required endpoints (e.g., health, info, prometheus) rather than using a wildcard (*) [6][4][7]. 5. Use a Separate Management Port: For enhanced security, consider running Actuator on a separate management port (management.server.port) that is not publicly accessible and can be protected by a firewall [6]. If you have secured your application and specifically require the always setting, ensure your security configuration explicitly permits access to the health endpoint for both authenticated and unauthenticated users, acknowledging the potential information disclosure [1][2].

Citations:


운영 환경의 SQL 및 헬스 엔드포인트에서 민감 정보 노출

show-sql: true는 SQL 쿼리와 데이터베이스 스키마를 로그에 노출시키며, 성능 저하를 유발합니다. show-details: always는 인증되지 않은 사용자도 데이터베이스 연결 정보와 내부 인프라 정보에 접근할 수 있게 합니다. 두 설정 모두 프로덕션 환경에서 비활성화해야 합니다.

수정 예시
-        show-sql: true
+        show-sql: false
@@
         health:
-            show-details: always
+            show-details: when-authorized
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@src/main/resources/application-prod.yml` at line 36, Change the production
YAML to stop logging SQL and exposing health details: set show-sql to false
(replace the current show-sql: true) and add or update the
management.endpoint.health.show-details property to a restrictive value like
never (or when-authorized) so health endpoint details are not exposed publicly;
target the settings shown as show-sql and
management.endpoint.health.show-details in application-prod.yml.

Comment thread .github/workflows/ci-prod.yml

@Sehi55 Sehi55 left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

확인했습니다

@ji-circle
ji-circle merged commit adb9112 into dev May 17, 2026
2 checks passed
@coderabbitai coderabbitai Bot mentioned this pull request May 19, 2026
3 tasks
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

enhancement New feature or request

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants