Skip to content

chore: 운영 환경 PostgreSQL 컨테이너 제거 및 외부 DB 연결 설정 보완#139

Merged
minbros merged 14 commits into
devfrom
feature/remove-prod-pg-container
Jun 8, 2026
Merged

chore: 운영 환경 PostgreSQL 컨테이너 제거 및 외부 DB 연결 설정 보완#139
minbros merged 14 commits into
devfrom
feature/remove-prod-pg-container

Conversation

@minbros

@minbros minbros commented Jun 8, 2026

Copy link
Copy Markdown
Member

변경 내용

  • compose.db.prod.yaml에서 로컬 postgres 서비스를 제거하고, 외부 PostgreSQL 인프라(AWS Lightsail Managed DB)에 연결할 수 있도록 설정을 조정했습니다.
  • postgres-exporterredis-exporter의 데이터 소스 연결 설정에 인증 정보와 SSL 설정을 반영했습니다.
  • redis 서비스에 패스워드 설정(--requirepass), 메모리 제한 설정(--maxmemory), 비영속 정책(--save "" --appendonly no)을 반영했습니다.
  • src/main/resources/application-prod.yaml에 외부 DB 접속을 위한 세부 타임아웃 파라미터(PostgreSQL, MongoDB) 및 HikariCP 설정(connection-timeout, validation-timeout, pool-size 등), Redis 패스워드/데이터베이스 세부 설정을 적용했습니다.
  • 이에 맞게 ProdDatabaseConfigTest.java 테스트 코드를 추가/수정하여 운영 환경의 DB 연결 사양을 검증할 수 있도록 조치했습니다.
  • CONTRIBUTING.md에 PR 대상 브랜치 명세를 명확히 하고, infra/monitoring/README.md에 DB 서버 운영 구성 요소를 최신화했습니다.

변경 이유

  • 운영 환경(AWS Lightsail)의 PostgreSQL 데이터베이스는 도커 컨테이너가 아닌 Managed DB를 활용하므로 도커 컴포즈 상에서 이를 제거하고, 외부 연결에 적합한 타임아웃, 커넥션 풀, SSL 모드 설정을 보강했습니다.
  • Redis의 메모리 정책 및 비영속 보조 캐시로서의 정책을 반영하고 보안 강화를 위해 비밀번호를 설정했습니다.

테스트

  • ./gradlew build
  • /review-code-against-docs 스킬로 검증
  • 그 외 수동 검증: Checkstyle 및 전체 단위 테스트 로컬 통과 완료

체크리스트

  • PR 제목이 커밋 컨벤션 형식을 따른다.
  • 변경 사유를 PR 설명에 기록했다.
  • 테스트 방법과 결과를 기록했다.
  • 문서 변경이 필요한 경우 반영했다.

하네스 변경 체크리스트

  • CLAUDE.md(AGENTS.md) 변경이 포함되어 있는가? (포함 안 됨 - 해당 없음)
  • 변경 사유가 PR 설명에 기록되어 있는가?
  • 기존 규칙과 충돌하지 않는가?
  • 팀원에게 변경 사항을 공유했는가?

Summary by CodeRabbit

  • 새 기능

    • Redis 인증 및 메모리 정책 예시 추가
    • MongoDB 마이그레이션 및 메시지 인덱스 자동 생성 기능 추가
    • 요청 본문 크기 제한(1MB) 적용
  • 개선 사항

    • 프로덕션 DB/Redis 연결 타임아웃·SSL·풀 설정 강화
    • 배포 워크플로우에 Redis 비밀번호 검증 항목 추가
    • 개발/테스트용 DB 이미지 및 버전 정비, exporter 중심 구성으로 전환
  • 테스트

    • 프로덕션 환경 구성 검증용 자동 테스트 추가
  • 문서

    • 브랜치 전략·운영 가이드 및 운영 문서 전반 업데이트

@coderabbitai

coderabbitai Bot commented Jun 8, 2026

Copy link
Copy Markdown

Review Change Stack

📝 Walkthrough

Walkthrough

이 PR은 프로덕션 DB/모니터링 구성과 CI 검증을 Redis 인증·exporter 중심으로 재구성하고, Mongock 기반 MongoDB 마이그레이션(메시지 인덱스 추가), 관련 테스트·문서·테스트컨테이너 이미지 업데이트를 포함합니다.

Changes

Production Database Hardening and Migrations

Layer / File(s) Summary
Production configuration and request limits
.env.db.example, src/main/resources/application-prod.yaml, infra/caddy/Caddyfile
Postgres JDBC/Hikari 타임아웃·풀 설정, MongoDB URI/풀 파라미터, Redis database/password 및 rate-limit 연동, Caddy request_body max_size 1MB 적용.
Redis service & exporter wiring
compose.db.prod.yaml, .env.db.example
Redis 서비스에 env_file--requirepass ${REDIS_PASSWORD} 헬스체크 적용; redis-exporterREDIS_PASSWORD 주입.
Compose cleanup and exporter rebase
compose.db.prod.yaml, compose.db.dev.yaml
Prod에서 local postgres 제거, postgres-exporter가 managed DB 호스트(${DB_HOST})와 sslmode=require 사용하도록 변경, volumes 정리 및 Mongo 이미지 태그 상향.
Production config validation tests
src/test/java/com/howaboutus/backend/common/config/ProdDatabaseConfigTest.java
JUnit 테스트로 JDBC URL 쿼리 파라미터·Hikari 설정, Mongo URI/타임아웃·풀 크기, Redis DB 바인딩, compose의 Redis 런타임 옵션(maxmemory, noeviction) 검증.
CI/CD deploy checks
.github/workflows/deploy-compose.yml, .github/workflows/deploy-db.yml
.env.prod/.env.db에 대한 REDIS_PASSWORD 존재 검증 추가. DB 배포 워크플로우의 서비스 목록과 실패 로그 타겟을 exporter 중심으로 갱신.
Docs, branching, and monitoring updates
CONTRIBUTING.md, .claude/skills/review-code-against-docs/SKILL.md, infra/monitoring/README.md, AGENTS.md, README.md, docs/ai/erd.md
브랜치 전략( feature→dev, dev→main, hotfix→main+backmerge) 명시, 코드 리뷰 스킬의 기준 브랜치/git diff 수집 절차 갱신, 모니터링 문서에 Redis 보안/용량·exporter 타겟 추가, 기술 스택/문서에서 PostGIS 관련 표기 수정.
Build deps: Mongock added
build.gradle
Mongock 및 MongoDB sync driver 의존성 추가.
Dev compose healthcheck and specs
compose.db.dev.yaml, docs/superpowers/specs/2026-06-08-postgresql-docker-healthcheck-design.md, docs/superpowers/plans/2026-06-08-postgresql-docker-healthcheck.md
Postgres 헬스체크를 Unix socket->TCP(pg_isready -h localhost -p 5432)로 변경하는 설계·검증 문서 추가.
MongoDB Mongock migration and indexes
src/main/java/.../MongoMigrationConfig.java, src/main/java/.../CreateMessageIndexesChangeUnit.java, src/main/java/.../ChatMessage.java, src/test/.../MongoMessageIndexMigrationTest.java, scripts/mongo/backfill-message-sequence.js
Mongock ApplicationRunner 등록, 메시지 컬렉션에 (roomId,sequence) 유니크 포함 4개 인덱스 생성 ChangeUnit 추가, 엔티티에 CompoundIndex 주석 추가, 인덱스 생성 테스트 추가, 기존 백필 스크립트 제거.
Integration test container images
src/test/java/.../BaseIntegrationTest.java
Testcontainers 이미지 태그를 postgres:17.10, mongo:8.0.21로 업데이트.

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~45 minutes

Poem

🐰 밤밭에서 깡충 뛰며 말하네,
비밀번호는 당근보다 소중해,
익스포터가 빛나고 인덱스가 빼꼼,
테스트가 검증해 안심한 밤,
배포는 달빛 아래 안전히 흐르네.

🚥 Pre-merge checks | ✅ 4
✅ Passed checks (4 passed)
Check name Status Explanation
Title check ✅ Passed PR 제목은 '운영 환경 PostgreSQL 컨테이너 제거 및 외부 DB 연결 설정 보완'으로, 주요 변경 사항인 compose.db.prod.yaml에서 postgres 서비스 제거 및 외부 DB 연결 설정을 명확히 요약하고 있습니다.
Description check ✅ Passed PR 설명은 변경 내용, 변경 이유, 테스트 방법을 모두 포함하고 있으며, 제공된 템플릿의 필수 섹션을 충족하고 있습니다. 체크리스트도 완성되어 있습니다.
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.


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: 1

Caution

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

⚠️ Outside diff range comments (2)
src/main/resources/application-prod.yaml (1)

34-37: ⚠️ Potential issue | 🟠 Major | ⚡ Quick win

spring.jpa.open-in-view=false 설정이 누락되었습니다.

운영 프로파일에서 spring.jpa.open-in-view가 명시되지 않아 가이드라인을 충족하지 못합니다. 명시적으로 false를 추가해 주세요.

🔧 제안 수정안
 spring:
   jpa:
+    open-in-view: false
     hibernate:
       ddl-auto: validate

As per coding guidelines, src/main/resources/application*.yaml: Keep spring.jpa.open-in-view=false configuration setting.

🤖 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.yaml` around lines 34 - 37, The
production YAML is missing the spring.jpa.open-in-view setting; update
src/main/resources/application-prod.yaml to explicitly add
spring.jpa.open-in-view: false under the spring.jpa configuration (alongside
jpa.hibernate.ddl-auto: validate) so the production profile enforces
open-in-view=false as required by the guidelines.

Source: Coding guidelines

.github/workflows/deploy-db.yml (1)

53-59: ⚠️ Potential issue | 🟠 Major | ⚡ Quick win

필수 DB/Mongo 접속 변수 검증을 함께 추가해 주세요.

지금 검증은 포트와 REDIS_PASSWORD 중심이라, DB_HOST/DB_NAME/DB_USER/DB_PASSWORD 또는 Mongo 필수값이 비어 있어도 배포 단계에서 늦게 실패할 수 있습니다. Validate 단계에서 미리 차단하는 편이 안전합니다.

🔧 제안 수정안
           grep '^DB_PRIVATE_IP=' .env.db
+          grep '^DB_HOST=.' .env.db
+          grep '^DB_NAME=.' .env.db
+          grep '^DB_USER=.' .env.db
+          grep '^DB_PASSWORD=.' .env.db
+          grep '^MONGO_USER=.' .env.db
+          grep '^MONGO_PASSWORD=.' .env.db
+          grep '^MONGO_DB=.' .env.db
           grep '^POSTGRES_EXPORTER_PORT=' .env.db
           grep '^REDIS_EXPORTER_PORT=' .env.db
           grep '^MONGODB_EXPORTER_PORT=' .env.db
           grep '^REDIS_PASSWORD=.' .env.db
🤖 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/deploy-db.yml around lines 53 - 59, Add mandatory
env-variable checks to the workflow: extend the existing grep validation block
(the lines that currently check DB_PRIVATE_IP, POSTGRES_EXPORTER_PORT,
REDIS_EXPORTER_PORT, MONGODB_EXPORTER_PORT, REDIS_PASSWORD) to also assert
non-empty DB_HOST, DB_NAME, DB_USER, DB_PASSWORD and the required Mongo vars
(e.g. MONGO_HOST, MONGO_DB, MONGO_USER, MONGO_PASSWORD or whatever keys your app
uses). Ensure each grep uses a pattern like '^VAR_NAME=.' and that the script
exits non‑zero on failure so docker compose validation doesn't run with missing
DB/Mongo credentials. Include clear names of the variables in the checks to
surface missing settings early.
🤖 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 `@infra/monitoring/README.md`:
- Around line 71-72: The DB server components list is missing postgres-exporter
which conflicts with other sections; update the DB 서버 운영 compose description to
include "postgres-exporter" alongside redis-exporter, mongodb-exporter, and
node-exporter, and ensure the README's service list, the POSTGRES_EXPORTER_PORT
reference, and the target example (target 예시) all consistently reflect the
postgres-exporter service name and port so the documentation matches the actual
monitoring targets.

---

Outside diff comments:
In @.github/workflows/deploy-db.yml:
- Around line 53-59: Add mandatory env-variable checks to the workflow: extend
the existing grep validation block (the lines that currently check
DB_PRIVATE_IP, POSTGRES_EXPORTER_PORT, REDIS_EXPORTER_PORT,
MONGODB_EXPORTER_PORT, REDIS_PASSWORD) to also assert non-empty DB_HOST,
DB_NAME, DB_USER, DB_PASSWORD and the required Mongo vars (e.g. MONGO_HOST,
MONGO_DB, MONGO_USER, MONGO_PASSWORD or whatever keys your app uses). Ensure
each grep uses a pattern like '^VAR_NAME=.' and that the script exits non‑zero
on failure so docker compose validation doesn't run with missing DB/Mongo
credentials. Include clear names of the variables in the checks to surface
missing settings early.

In `@src/main/resources/application-prod.yaml`:
- Around line 34-37: The production YAML is missing the spring.jpa.open-in-view
setting; update src/main/resources/application-prod.yaml to explicitly add
spring.jpa.open-in-view: false under the spring.jpa configuration (alongside
jpa.hibernate.ddl-auto: validate) so the production profile enforces
open-in-view=false as required by the guidelines.
🪄 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: cec519a9-6400-4237-9cfb-4121e25ecf14

📥 Commits

Reviewing files that changed from the base of the PR and between beef4a2 and 438fb43.

📒 Files selected for processing (10)
  • .claude/skills/review-code-against-docs/SKILL.md
  • .env.db.example
  • .github/workflows/deploy-compose.yml
  • .github/workflows/deploy-db.yml
  • CONTRIBUTING.md
  • compose.db.prod.yaml
  • infra/caddy/Caddyfile
  • infra/monitoring/README.md
  • src/main/resources/application-prod.yaml
  • src/test/java/com/howaboutus/backend/common/config/ProdDatabaseConfigTest.java

Comment thread infra/monitoring/README.md
@minbros minbros temporarily deployed to production-db June 8, 2026 11:45 — with GitHub Actions Inactive
@minbros minbros temporarily deployed to production-monitoring June 8, 2026 11:45 — with GitHub Actions Inactive
@minbros minbros temporarily deployed to production-api June 8, 2026 11:47 — with GitHub Actions Inactive
@minbros minbros temporarily deployed to production-db June 8, 2026 11:50 — with GitHub Actions Inactive
@sonarqubecloud

sonarqubecloud Bot commented Jun 8, 2026

Copy link
Copy Markdown

@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.

Caution

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

⚠️ Outside diff range comments (1)
src/main/java/com/howaboutus/backend/messages/document/ChatMessage.java (1)

18-23: ⚠️ Potential issue | 🟡 Minor

Spring Data 자동 인덱스 생성 가이드라인 정리 권장

  • ChatMessage@CompoundIndexesCreateMessageIndexesChangeUnit에서 동일 인덱스를 명시적으로 생성하는 구조와 중복됩니다.
  • application*.yamlspring.data.mongodb.auto-index-creation을 켜는 설정은 없고, Spring Boot 4.0.5 기본값은 false라 자동 인덱스 생성 충돌 가능성은 낮습니다.
  • 그래도 기본값에 의존하지 않으려면 spring.data.mongodb.auto-index-creation: false를 명시하거나(가이드라인 준수), 인덱스 중복/오해를 줄이기 위해 @CompoundIndexes를 제거하는 쪽으로 정리하는 것을 권장합니다.
🤖 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/java/com/howaboutus/backend/messages/document/ChatMessage.java`
around lines 18 - 23, The ChatMessage class currently declares `@CompoundIndexes`
which duplicates the explicit index creation in CreateMessageIndexesChangeUnit;
to avoid confusion and potential conflicts, either remove the `@CompoundIndexes`
annotation from the ChatMessage entity (preferred to keep indexing centralized
in CreateMessageIndexesChangeUnit) or explicitly disable auto index creation by
adding spring.data.mongodb.auto-index-creation: false to application*.yaml;
locate the ChatMessage class and the `@CompoundIndexes` block to delete it if
removing, or update the application configuration to set the property if you
choose to keep the annotation.

Source: Coding guidelines

🧹 Nitpick comments (1)
src/test/java/com/howaboutus/backend/common/migration/MongoMessageIndexMigrationTest.java (1)

23-42: ⚡ Quick win

마이그레이션 멱등성(idempotency) 테스트를 추가하는 것을 권장합니다.

현재 테스트는 빈 MongoDB에서 인덱스 생성을 검증하지만, 마이그레이션을 두 번 실행했을 때 에러 없이 성공하는지(멱등성)도 검증하면 더욱 견고합니다. Mongock은 이미 실행된 ChangeUnit을 추적하므로 중복 실행을 방지하지만, 이를 명시적으로 테스트하면 신뢰성이 높아집니다.

🧪 멱등성 테스트 예시
`@Test`
`@DisplayName`("Mongock 마이그레이션은 멱등성을 보장한다 (중복 실행 시 에러 없음)")
void mongockMigrationIsIdempotent() {
    // Given: 이미 인덱스가 생성된 상태
    assertThat(mongoTemplate.collectionExists("messages")).isTrue();
    
    // When: 마이그레이션을 다시 실행 시도 (실제로는 Mongock이 스킵하지만 검증 차원)
    // Mongock은 이미 실행된 ChangeUnit을 다시 실행하지 않으므로
    // 여기서는 인덱스가 이미 존재하는 상태에서 createIndex를 호출해도 에러가 없음을 확인
    
    // Then: 인덱스가 여전히 정상적으로 존재
    Map<String, Document> indexesByName = mongoTemplate.getCollection("messages")
        .listIndexes()
        .into(new ArrayList<>())
        .stream()
        .collect(Collectors.toMap(index -> index.getString("name"), Function.identity()));
    
    assertThat(indexesByName).hasSize(5); // _id 포함 5개
}
🤖 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/test/java/com/howaboutus/backend/common/migration/MongoMessageIndexMigrationTest.java`
around lines 23 - 42, Add an idempotency test to MongoMessageIndexMigrationTest
named mongockMigrationIsIdempotent that ensures re-running the migration (or
invoking the same index-creation logic again) does not fail and leaves indexes
intact: set up/verify the "messages" collection exists, re-execute the migration
path (or directly call the index-creation routine in the migration class),
collect indexes via the same
getCollection(...).listIndexes().into(...).stream()... pattern used in
mongockCreatesMessageIndexesOnEmptyMongo, and assert the expected number/names
of indexes (e.g., include _id so total size is 5) and that existing indexes
remain unchanged. Use the same helper/assertIndex logic and reference
MongoMessageIndexMigrationTest and the new method mongockMigrationIsIdempotent.
🤖 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.

Outside diff comments:
In `@src/main/java/com/howaboutus/backend/messages/document/ChatMessage.java`:
- Around line 18-23: The ChatMessage class currently declares `@CompoundIndexes`
which duplicates the explicit index creation in CreateMessageIndexesChangeUnit;
to avoid confusion and potential conflicts, either remove the `@CompoundIndexes`
annotation from the ChatMessage entity (preferred to keep indexing centralized
in CreateMessageIndexesChangeUnit) or explicitly disable auto index creation by
adding spring.data.mongodb.auto-index-creation: false to application*.yaml;
locate the ChatMessage class and the `@CompoundIndexes` block to delete it if
removing, or update the application configuration to set the property if you
choose to keep the annotation.

---

Nitpick comments:
In
`@src/test/java/com/howaboutus/backend/common/migration/MongoMessageIndexMigrationTest.java`:
- Around line 23-42: Add an idempotency test to MongoMessageIndexMigrationTest
named mongockMigrationIsIdempotent that ensures re-running the migration (or
invoking the same index-creation logic again) does not fail and leaves indexes
intact: set up/verify the "messages" collection exists, re-execute the migration
path (or directly call the index-creation routine in the migration class),
collect indexes via the same
getCollection(...).listIndexes().into(...).stream()... pattern used in
mongockCreatesMessageIndexesOnEmptyMongo, and assert the expected number/names
of indexes (e.g., include _id so total size is 5) and that existing indexes
remain unchanged. Use the same helper/assertIndex logic and reference
MongoMessageIndexMigrationTest and the new method mongockMigrationIsIdempotent.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro Plus

Run ID: a55de585-db76-4110-8099-1425276cebef

📥 Commits

Reviewing files that changed from the base of the PR and between 438fb43 and 37dc2dc.

📒 Files selected for processing (16)
  • AGENTS.md
  • README.md
  • build.gradle
  • compose.db.dev.yaml
  • compose.db.prod.yaml
  • docs/ai/erd.md
  • docs/superpowers/plans/2026-06-08-postgresql-docker-healthcheck.md
  • docs/superpowers/plans/2026-06-08-remove-postgis.md
  • docs/superpowers/specs/2026-06-08-postgresql-docker-healthcheck-design.md
  • docs/superpowers/specs/2026-06-08-remove-postgis-design.md
  • scripts/mongo/backfill-message-sequence.js
  • src/main/java/com/howaboutus/backend/common/config/MongoMigrationConfig.java
  • src/main/java/com/howaboutus/backend/common/migration/mongo/CreateMessageIndexesChangeUnit.java
  • src/main/java/com/howaboutus/backend/messages/document/ChatMessage.java
  • src/test/java/com/howaboutus/backend/common/migration/MongoMessageIndexMigrationTest.java
  • src/test/java/com/howaboutus/backend/support/BaseIntegrationTest.java
💤 Files with no reviewable changes (1)
  • scripts/mongo/backfill-message-sequence.js
✅ Files skipped from review due to trivial changes (3)
  • README.md
  • docs/superpowers/specs/2026-06-08-postgresql-docker-healthcheck-design.md
  • docs/superpowers/specs/2026-06-08-remove-postgis-design.md
🚧 Files skipped from review as they are similar to previous changes (1)
  • compose.db.prod.yaml

@minbros minbros merged commit 9c1a8e7 into dev Jun 8, 2026
4 checks passed
@minbros minbros deleted the feature/remove-prod-pg-container branch June 8, 2026 13:54
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant