Skip to content

Repository files navigation

PromSearch Backend

프롬써치(PromSearch) MVP 백엔드 API 서버입니다. 아웃풋(결과물) 중심 프롬프트 탐색 → 로그인/가입 → 상세 조회 → 복사/추천/업로드 → 집계/등급/운영 관리 흐름을 지원합니다.

기술 스택

  • 언어: Java 21 (LTS)
  • 프레임워크: Spring Boot 3.5.16
  • 빌드 도구: Gradle
  • 컨테이너: Docker (멀티스테이지 빌드, eclipse-temurin:21)
  • 배포: AWS EC2 (Docker 컨테이너 직접 배포)
  • 이미지 레지스트리: Docker Hub
  • CI/CD: GitHub Actions

로컬 실행 방법

./gradlew bootRun

정상 실행되면 아래 주소로 헬스체크 확인:

http://localhost:8080/test/health-check
→ OK

이미지 Worker 실행

이미지 Worker는 API와 별도 JVM으로 실행되며 HTTP 포트를 열지 않습니다. 두 JVM은 같은 이미지 상태를 봐야 하므로 SPRING_DATASOURCE_URL에 동일한 외부 DB를 지정해야 합니다. 인메모리 H2는 프로세스 사이에 공유되지 않습니다.

./gradlew :worker:bootRun

API는 업로드 완료와 같은 트랜잭션에 Outbox 작업을 저장하고, 별도 발행기가 이를 SQS로 전달합니다. Worker는 SQS Long Polling으로 한 건씩 받아 S3 다운로드, 반복 wordmark 합성, 결과 업로드, PROCESSING → READY/FAILED 상태 전환을 수행합니다. 처리가 끝난 메시지만 삭제하며 실패 메시지는 Visibility Timeout 이후 재시도되고 큐의 Redrive Policy에 따라 DLQ로 이동합니다.

워터마크의 투명도·로고 크기·간격·여백은 WATERMARK_* 환경변수로 조정할 수 있습니다. 기본값은 1280×720 기준 짝수 행 5개, 홀수 행 4개가 반 칸씩 교차하는 시안을 따릅니다.

Docker로 로컬 실행

docker build -t promsearch .
docker run -p 8080:8080 promsearch

# 동일한 이미지에서 HTTP 서버 없이 이미지 Worker 실행
docker run --no-healthcheck promsearch worker.jar

API와 Worker 컨테이너에는 동일한 SPRING_DATASOURCE_*, AWS_S3_BUCKET, AWS_SQS_WATERMARK_* 환경변수를 전달해야 합니다. Flyway의 PostgreSQL 런타임 의존성은 API 이미지에 포함됩니다. 새 빈 PostgreSQL에는 SPRING_FLYWAY_ENABLED=true를 전달해 V1__create_initial_schema.sql을 적용하고, SPRING_FLYWAY_BASELINE_ON_MIGRATEfalse로 유지합니다. Worker는 Flyway를 실행하지 않으며 운영 배포는 API 헬스체크 성공 후 Worker를 시작합니다. 기존 V1~V8을 적용한 로컬 DB는 새 V1과 Flyway 체크섬이 호환되지 않으므로 데이터를 보존할 필요가 없을 때 DB를 재생성해야 합니다. 기존 데이터가 있는 DB에는 이 초기화를 적용하지 않습니다.

배포된 서버 확인

http://[EC2_퍼블릭_IP]:8080/test/health-check

실제 IP는 팀 내부 인프라 문서(Notion) 참고. 이 값은 보안상 README에 직접 기재하지 않습니다.

브랜치 전략

main            → 배포 브랜치 (protected, 직접 push 불가)
develop         → 개발 통합 브랜치 (protected, 직접 push 불가)
feature/기능명   → 작업 브랜치, 예: feature/auth-login, feature/prompt-upload
  • develop으로 머지하려면:
    1. feature/* 브랜치에서 작업 후 PR 생성 (base: develop)
    2. CI(build-and-test) 통과
    • 이 단계는 검증만 수행하며 배포는 발생하지 않습니다.
  • main으로 머지하려면:
    1. develop이 릴리스 준비되면 developmain PR 생성
    2. 팀원 1명 이상 승인(Approve)
    3. CI(build-and-test) 통과
    • 위 조건 미충족 시 GitHub이 머지 버튼을 자동으로 막습니다.
  • main, develop 모두 직접 push 및 force push는 차단되어 있습니다.

CI/CD 동작 방식

[feature 브랜치 push / PR → develop] → CI 실행 (빌드 + 테스트)
                                          └ 배포 없음, 개발 중 자유롭게 반복 가능

[develop → main PR 승인 + 머지] → CI 재실행 → 성공 시에만 CD 실행
                                    └ Docker 이미지 빌드 → Docker Hub 푸시 (latest + git sha 태그)
                                    → EC2 SSH 접속 → 컨테이너 재기동
                                    └ 실패 시 Discord #ci-cd 채널 알림
  • CI(ci.yml)는 develop, main 두 브랜치를 대상으로 push/PR 시 Gradle 빌드·테스트와 Docker 이미지 빌드를 실행합니다.
  • 배포(deploy.yml)는 workflow_run + branches: [main] 조건으로 main에서 CI가 성공했을 때만 트리거됩니다. develop에서의 CI 성공은 배포를 트리거하지 않습니다.
  • CI가 실패한 커밋은 절대 배포되지 않습니다 (conclusion == 'success' 조건으로 연결).
  • 배포된 컨테이너는 --restart unless-stopped로 EC2 재부팅 시에도 자동 기동됩니다.
  • 배포 시마다 이전 이미지는 docker image prune -f로 정리됩니다.

커밋 전 체크리스트

  • ./gradlew build 로컬에서 통과 확인 (CI 실패 최소화)
  • 커밋 메시지 컨벤션 확인 (팀 컨벤션 문서 링크 추가 예정)
  • 민감정보(API 키, 비밀번호 등)를 코드/설정 파일에 하드코딩하지 않았는지 확인

프로젝트 문서

  • API 명세서 / ERD: (링크 추가 예정)
  • 팀 개발 컨벤션: (링크 추가 예정)
  • CI/CD 파이프라인 · 배포 인프라 상세: INFRA_REFERENCE.md
  • 인프라 인증정보(EC2 IP, 키 등): 팀 Notion (비공개) — GitHub에는 올리지 않습니다.

About

PrompSearch-BE

Resources

Contributing

Security policy

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages