Skip to content

[Chore] Spring Boot 운영 환경 설정 및 Secret 분리 - #75

Merged
pearseona merged 5 commits into
developfrom
chore/73-prod-config
Aug 2, 2026
Merged

[Chore] Spring Boot 운영 환경 설정 및 Secret 분리 #75
pearseona merged 5 commits into
developfrom
chore/73-prod-config

Conversation

@pearseona

@pearseona pearseona commented Aug 2, 2026

Copy link
Copy Markdown
Contributor

📋 작업 내용

Spring Boot 개발·운영 환경 설정을 분리한다.
운영 전용 prod 프로파일을 구성한다.
운영에 필요한 환경변수 목록과 .env.example을 작성한다.
운영 환경에서 DB 및 RabbitMQ의 개발용 기본 인증정보를 사용하지 않도록 한다.
Firebase 서비스 계정의 운영 주입 방식을 구성한다.
Secret과 Firebase 서비스 계정 파일이 Git 및 Docker 이미지에 포함되지 않도록 .gitignore, .dockerignore를 점검한다.
로그에서 JWT, API Key, 전화번호, 문자 원문 등 Secret과 개인정보가 노출되지 않도록 점검한다.

🧪 테스트 결과

  • ./gradlew clean test bootJar --no-daemon 통과
  • 전체 테스트 123개 통과
  • 운영 JAR(bootJar) 빌드 통과
  • docker compose config --quiet --no-interpolate 통과
  • git diff --check 통과
  • Docker Compose에서 PostgreSQL 5432, RabbitMQ 5672/15672, FastAPI 8000 포트가 노출되지 않는 것을 확인했습니다.
  • 빌드된 JAR에 .env, Firebase 서비스 계정 JSON, PEM 및 Key 파일이 포함되지 않은 것을 확인했습니다.

🔗 관련 이슈

Closes #73

✅ 체크리스트

  • 관련 이슈를 연결했습니다.
  • 구현 범위와 변경 이유를 설명했습니다.
  • 로컬 테스트를 통과했습니다.
  • API 변경 사항을 Swagger에 반영했습니다.
  • DB 변경 사항과 마이그레이션을 포함했습니다.
  • 민감 정보가 코드·로그·테스트 데이터에 포함되지 않았습니다.
  • 프론트엔드에 영향을 주는 응답 스키마 또는 Enum 변경을 공유했습니다.
  • 병합 전 작업 브랜치를 삭제하지 않았습니다.

📌 배포 참고 사항

  • EC2에 설치된 Nginx는 Spring을 http://127.0.0.1:8080으로 프록시해야 합니다.
  • 실제 운영 .env 및 Secret은 Git에 커밋하지 않고 AWS Parameter Store에서 런타임에 주입해야 합니다.
  • Firebase 서비스 계정 파일은 EC2에 생성한 뒤 컨테이너의 /run/secrets/firebase/service-account.json으로 읽기 전용 마운트해야 합니다.
  • 노출된 기존 Gemini API Key는 폐기하고 새 키를 발급하여 등록해야 합니다.

Summary by CodeRabbit

  • New Features
    • Added production configuration templates for databases, messaging, authentication, notifications, and external integrations.
    • Added controls to enable or disable Firebase services and analysis message processing.
  • Security
    • Removed local credential defaults and strengthened protection for environment files, secrets, certificates, and service-account credentials.
    • Restricted backend access to localhost by default.
  • Configuration
    • Disabled API documentation and Swagger UI in production.
    • Added clearer environment-based configuration for deployment.
  • Bug Fixes
    • Improved notification error logging by excluding sensitive details.

@coderabbitai

coderabbitai Bot commented Aug 2, 2026

Copy link
Copy Markdown

Review Change Stack

Warning

Review limit reached

@pearseona, you've reached your PR review limit, so we couldn't start this review.

Next review available in: 50 minutes

Enable usage-based reviews in Billing to review now. Otherwise, wait until the next included review is available.
You're only billed for reviews past your plan's rate limits ($0.25/file).

How can I continue?

After more reviews become available, a review can be triggered using the @coderabbitai review command as a PR comment. Alternatively, push new commits to this PR.

To avoid repeated limits, reduce automatic review volume by pausing incremental auto-reviews earlier, using label-based review opt-in, excluding WIP or generated PR titles, or requesting reviews manually when the PR is ready. If your team needs uninterrupted high-volume reviews, an organization admin can enable usage-based reviews.

How do review limits work?

CodeRabbit enforces per-developer PR review limits for each organization. Most developers receive the normal plan review availability.

For paid Pro and Pro+ PR reviews, CodeRabbit uses adaptive limits for sustained high-volume activity. When a developer's recent PR review activity reaches the 95th percentile or higher among CodeRabbit users, additional reviews become available more gradually as earlier reviews age out of the rolling window.

Please refer docs for additional details.

Review details
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro Plus

Run ID: 976ac480-1442-45da-b270-424875fe6c98

📥 Commits

Reviewing files that changed from the base of the PR and between f316aff and 06a8c87.

📒 Files selected for processing (6)
  • .env.example
  • .env.prod.example
  • .github/workflows/backend-ci.yml
  • .gitignore
  • docker-compose.yml
  • src/main/java/com/gold/safefam/domain/notification/service/FcmService.java
📝 Walkthrough

Walkthrough

The change adds production Spring configuration, externalizes credentials, tightens Docker and Git exclusions, validates conditional Firebase initialization, limits service exposure, updates FCM logging, and makes the analysis consumer configurable.

Changes

Production runtime configuration

Layer / File(s) Summary
Deployment configuration and secret boundaries
.dockerignore, .gitignore, .env.example, .env.prod.example, docker-compose.yml
Environment templates define production variables. Compose requires credentials, mounts Firebase credentials, limits backend exposure, removes FastAPI port publishing, and removes Nginx.
Spring production and Firebase configuration
src/main/resources/application-prod.yml, src/main/resources/application.yml, src/main/java/com/gold/safefam/global/config/FirebaseConfig.java
The prod profile externalizes service settings. Firebase initializes only when enabled and validates a readable regular service-account file.
Messaging and notification runtime controls
src/main/java/com/gold/safefam/domain/notification/service/FcmService.java, src/main/java/com/gold/safefam/infrastructure/messaging/rabbitmq/consumer/AnalysisResultConsumer.java, src/test/resources/application-test.yml
FCM logs use analysisId and messaging error codes without storing SDK responses or token data. The analysis consumer and RabbitMQ listeners use configurable startup behavior.

Estimated code review effort: 3 (Moderate) | ~25 minutes

Possibly related PRs

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title matches the primary change: separating Spring Boot production settings and secrets.
Linked Issues check ✅ Passed The changes address #73 through prod configuration, environment templates, runtime secrets, Firebase injection, secret exclusion, and sensitive-log reduction.
Out of Scope Changes check ✅ Passed All changes support #73 by configuring production deployment, protecting credentials, controlling consumers, or reducing sensitive logging.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch chore/73-prod-config

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.

@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

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
docker-compose.yml (1)

69-73: 🔒 Security & Privacy | 🟠 Major | ⚡ Quick win

Require production JWT and outbox secrets at Compose parse time.

${JWT_SECRET} and ${OUTBOX_ENCRYPTION_KEY_BASE64} become empty values when they are absent. This bypasses the unresolved-placeholder failure in application-prod.yml. Require both values with :? so deployment stops before the container starts.

Proposed fix
-      JWT_SECRET: ${JWT_SECRET}
+      JWT_SECRET: ${JWT_SECRET:?JWT_SECRET is required}
@@
-      OUTBOX_ENCRYPTION_KEY_BASE64: ${OUTBOX_ENCRYPTION_KEY_BASE64}
+      OUTBOX_ENCRYPTION_KEY_BASE64: ${OUTBOX_ENCRYPTION_KEY_BASE64:?OUTBOX_ENCRYPTION_KEY_BASE64 is required}
🤖 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 `@docker-compose.yml` around lines 69 - 73, Update the JWT_SECRET and
OUTBOX_ENCRYPTION_KEY_BASE64 entries in the Compose environment configuration to
use required-variable syntax with :?, so Compose fails during parsing when
either production secret is absent while leaving the expiration defaults
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 @.dockerignore:
- Around line 11-16: Update the Docker ignore patterns to explicitly exclude the
bare .env file in addition to the existing .env.* pattern, while preserving all
current secret and credential exclusions.

In @.env.example:
- Around line 1-30: Update the .env.example variable names to match
docker-compose.yml, replacing the DB_* connection entries with POSTGRES_USER,
POSTGRES_PASSWORD, and POSTGRES_DB, and replacing FIREBASE_SERVICE_ACCOUNT_PATH
with FIREBASE_SERVICE_ACCOUNT_HOST_PATH. Ensure the resulting template can be
copied directly for the documented Compose startup flow.

In `@docker-compose.yml`:
- Line 60: Update docker-compose.yml lines 60-60 and 112-112 so both Spring and
FastAPI use a pre-percent-encoded RABBITMQ_URL, or configure each client with
separate host, username, and password properties instead of interpolating raw
credentials into the AMQP URI. Apply the same URI-safe configuration
consistently at both sites.

---

Outside diff comments:
In `@docker-compose.yml`:
- Around line 69-73: Update the JWT_SECRET and OUTBOX_ENCRYPTION_KEY_BASE64
entries in the Compose environment configuration to use required-variable syntax
with :?, so Compose fails during parsing when either production secret is absent
while leaving the expiration defaults 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: defaults

Review profile: CHILL

Plan: Pro Plus

Run ID: f2f11b9e-0e11-407f-8fd0-67ec8212c423

📥 Commits

Reviewing files that changed from the base of the PR and between 4de1efc and 5680cc3.

📒 Files selected for processing (11)
  • .dockerignore
  • .env.example
  • .env.prod.example
  • .gitignore
  • docker-compose.yml
  • src/main/java/com/gold/safefam/domain/notification/service/FcmService.java
  • src/main/java/com/gold/safefam/global/config/FirebaseConfig.java
  • src/main/java/com/gold/safefam/infrastructure/messaging/rabbitmq/consumer/AnalysisResultConsumer.java
  • src/main/resources/application-prod.yml
  • src/main/resources/application.yml
  • src/test/resources/application-test.yml

Comment thread .dockerignore
Comment on lines +11 to +16
.env.*
secrets
**/firebase-service-account*.json
**/service-account*.json
*.pem
*.key

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

🔒 Security & Privacy | 🟠 Major | ⚡ Quick win

Exclude the bare .env file.

.env.* does not match .env. A production .env file can enter the Docker build context and can be copied into an image layer or build cache.

Proposed fix
+.env
 .env.*
 secrets
📝 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
.env.*
secrets
**/firebase-service-account*.json
**/service-account*.json
*.pem
*.key
.env
.env.*
secrets
**/firebase-service-account*.json
**/service-account*.json
*.pem
*.key
🤖 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 @.dockerignore around lines 11 - 16, Update the Docker ignore patterns to
explicitly exclude the bare .env file in addition to the existing .env.*
pattern, while preserving all current secret and credential exclusions.

Comment thread .env.example Outdated
Comment thread docker-compose.yml Outdated
pearseona and others added 3 commits August 2, 2026 19:34
@pearseona
pearseona merged commit c796df0 into develop Aug 2, 2026
4 checks passed
@pearseona pearseona self-assigned this Aug 2, 2026
@pearseona pearseona added the chore Configuration, environment, build tasks label Aug 2, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

chore Configuration, environment, build tasks

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[Chore] Spring Boot 운영 환경 설정 및 Secret 분리

1 participant