Skip to content

[chore] 배포 환경 구축 및 CD 파이프라인 추가 - #8

Merged
theminjunchoi merged 16 commits into
devfrom
chore/7-deployment
Jul 21, 2026
Merged

[chore] 배포 환경 구축 및 CD 파이프라인 추가#8
theminjunchoi merged 16 commits into
devfrom
chore/7-deployment

Conversation

@theminjunchoi

@theminjunchoi theminjunchoi commented Jul 17, 2026

Copy link
Copy Markdown
Collaborator

🔗 연관 이슈

📌 개요

가비아 클라우드 서버 2대(dev·prod)에 앱과 MySQL을 띄우고, dev·prod 브랜치 push 시 자동 배포되는 CD 파이프라인을 붙입니다. 무중단 배포는 하지 않고 단순 재시작 방식으로 시작합니다.

🔧 주요 변경사항

배포 산출물

  • Dockerfile — JDK 빌드 / JRE 런타임 2단계, 비루트 실행, exec로 SIGTERM 정상 처리
  • deploy/{dev,prod}/docker-compose.yml — app + MySQL + nginx (서버당 한 벌)
  • deploy/nginx/conf/gamss.conf — 리버스 프록시 (80 → app:8080)
  • deploy/setup-server.sh — 서버 초기 세팅 (Docker·방화벽·배포 디렉토리), 멱등

CD (.github/workflows/image.yml)

  • dev·prod push → 테스트·린트(ci.yml) 통과 → 이미지 빌드 후 GHCR push → 해당 서버에 SCP·SSH 배포
  • ci.ymlworkflow_call로 열어 CD가 호출 — 테스트가 깨지면 배포로 넘어가지 않습니다
  • 브랜치명으로 GitHub Environment를 골라 환경별 시크릿 주입
  • 이미지 태그는 커밋마다 고유(dev-a1b2c3d) — 롤백 기준

배포 스크립트 (.github/scripts/deploy-app.sh)

  • pull → up -d → 헬스체크 → 실패 시 이전 이미지 태그로 자동 롤백
  • 롤백 기준 IMAGE_TAG는 서버 .env에 기록하고 재배포 시 보존

수동 롤백 (.github/workflows/rollback.yml)

  • 배포는 성공했으나 버그가 발견된 경우, 환경·이미지 태그를 골라 이전 버전으로 되돌립니다
  • 서버의 deploy-app.sh를 재사용해 헬스체크·자동복구가 배포와 동일하게 동작
  • 태그가 대상 환경 접두사와 다르면 실행 전에 막아 prod에 dev 이미지를 올리는 사고를 방지

서버 사양 반영

  • 실제 서버(가비아 Standard 2vCore/8GB)에 맞춰 app 힙 3G, MySQL buffer pool 2G로 배분

🌐 API · DB 영향

  • API 변경: 없음 (actuator 헬스체크 엔드포인트만 추가, nginx에서 외부 노출 차단)
  • DB 마이그레이션: 없음
  • 하위 호환: 호환

💬 리뷰 포인트

1. nginx의 resolver 지시자 — 앱 컨테이너는 배포마다 재생성되며 IP가 바뀝니다. proxy_pass에 이름을 그대로 쓰면 nginx가 기동 시점 IP를 캐시해 재배포 후 502가 납니다. Docker 내장 DNS를 resolver로 두고 변수로 넘겨 매번 재해석하게 했습니다. 컨테이너 IP를 바꿔가며 검증했습니다.

2. 무중단 배포가 아닙니다 — 교체 시 20~40초 다운타임이 있습니다. Blue/Green은 nginx upstream 전환과 app 컨테이너 2개 동시 기동이 필요해 이번 범위에서 제외했습니다.

🧹 정리 완료

CodeRabbit 리뷰 반영

  • deploy-app.sh: set -e 하에서 docker compose up -d 실패 시 자동 롤백이 건너뛰어지던 것을 if !로 감싸 롤백으로 넘김
  • image.yml·rollback.yml: 워크플로 기본 packages 권한을 write→read 로 낮추고, push가 필요한 build-and-push job 에만 write 부여(최소 권한)
  • rollback.yml: 자유 형식 입력을 Summary 스크립트에 직접 보간하던 것을 env로 받아 참조(스크립트 인젝션 방지)
  • (반영 안 함) MySQL 헬스체크 무비번 → 실측 결과 mysqladmin ping은 Access denied 여도 exit 0(healthy)이라 오탐. nginx proxy_pass·액션 SHA 고정 등은 저위험/optional로 판단.

🚀 배포 순서 (이 PR 머지 = 첫 배포)

이 PR이 dev에 머지되면 CD가 dev 서버에 첫 배포를 시도합니다(이미지 빌드 → GHCR → SCP·SSH → up -d → 헬스체크). 현재 서버엔 아무것도 떠 있지 않은 상태라, 이 머지가 실제 첫 기동입니다.

  1. 도메인·DNSgamss.kr 구매 완료. A 레코드 전파 확인됨:
    • dev-api.gamss.kr139.150.11.145 (dev)
    • api.gamss.kr1.201.120.148 (prod)
  2. 이 PR 머지 → 첫 배포(HTTP)http://dev-api.gamss.kr 접근 확인
  3. HTTPS (후속 PR) — DNS가 서버를 가리키므로 배포 후 certbot으로 인증서 발급 → nginx 443 블록 전환. 앱은 iOS ATS 때문에 실서비스 전 HTTPS 필수. Let's Encrypt 특성상 "HTTP 배포 → 인증서 발급 → 443 전환" 순서라 이 PR 범위 밖의 후속으로 진행합니다.

🖥 서버 준비 상태

gamss-dev gamss-prod
사양 2vCore / 8GB / SSD 50GB 2vCore / 8GB / SSD 50GB
세팅 ✅ Docker·방화벽·~/app ✅ Docker·방화벽·~/app
GitHub Environment ✅ 시크릿 7개 ✅ 시크릿 7개
도메인(DNS) ✅ dev-api.gamss.kr ✅ api.gamss.kr

보안 그룹은 SSH 22 / HTTP 80 / HTTPS 443만 열려 있습니다 (기본값의 RDP 3389는 제거).

Summary by CodeRabbit

Summary by CodeRabbit

  • 새 기능

    • 개발/운영용 컨테이너 배포 구성을 추가하고, 리버스 프록시를 연동했습니다.
    • 빌드-푸시-배포 자동화 및 수동 롤백 워크플로를 도입했습니다.
    • 헬스체크 기반 배포 검증, 실패 시 자동 롤백을 지원합니다.
  • 개선

    • Actuator는 health만 노출하고 상세 정보는 숨겼습니다.
    • 경량 멀티 스테이지 실행 이미지와 비루트 실행으로 보안을 강화했습니다.
    • 개발/운영 환경 설정 및 DB 연결 구성을 정비했습니다.
  • 테스트

    • /actuator/health 인증 없이 200 UP을 확인하는 테스트를 추가했습니다.

@theminjunchoi theminjunchoi self-assigned this Jul 17, 2026
@theminjunchoi theminjunchoi linked an issue Jul 17, 2026 that may be closed by this pull request
20 tasks
Base automatically changed from feat/5-social-login to dev July 18, 2026 01:48
멀티스테이지 빌드로 실행 가능한 이미지를 만든다.

- build 스테이지: Gradle로 boot jar 빌드(테스트 제외)
- runtime 스테이지: JRE 21 경량 이미지, 비루트 유저 실행
- plain jar 비활성화로 boot jar만 패키징
- .dockerignore로 빌드 컨텍스트 최소화
dev·prod 브랜치 push 시 앱 이미지를 빌드해 GitHub Container Registry에 push한다.

- ghcr.io/nexters/gamss-server 에 브랜치명·커밋 SHA 태그로 push
- GITHUB_TOKEN으로 인증(별도 시크릿 불필요)
- buildx gha 캐시로 빌드 가속
가비아 VM 생성 후 서버를 준비하는 초기 세팅 스크립트를 추가한다.

- deploy/setup-server.sh: Docker 설치·방화벽·배포 유저·디렉토리 (멱등)
환경별 프로필과 서버용 docker-compose를 추가한다. 각 서버에서 앱과
MySQL을 함께 띄우며, 2GB 서버 기준으로 튜닝했다.

- application-dev.yml, application-prod.yml: datasource를 env로 주입
- deploy/{dev,prod}/docker-compose.yml: app + MySQL(외부 포트 비공개)
- 앱 힙 -Xmx768m, MySQL buffer pool 384M (사양 올리면 이 값만 상향)
배포 검증·모니터링용 /actuator/health를 추가한다.

- spring-boot-starter-actuator 의존성
- health 엔드포인트만 노출, show-details=never
- /actuator/health는 인증 없이 접근 허용(배포 헬스체크용)
이미지 빌드 후 dev/prod 서버에 SCP·SSH로 배포하는 job을 추가한다.
브랜치명으로 GitHub Environment를 골라 환경별 시크릿을 주입한다.

배포는 단순 재시작 방식이다(무중단 아님). 헬스체크에 실패하면
이전 이미지 태그로 되돌린다. 롤백 기준이 되는 IMAGE_TAG는
서버 .env에 기록해 두고 재배포 시 보존한다.
2GB 전제로 잡혀 있던 값을 실제 서버 사양(2vCore/8GB)에 맞춘다.
app 힙 768m→3g, MySQL buffer pool 384M→2G.

LLM 호출은 응답까지 스레드를 붙잡고 있어 동시성을 올리려면
스레드를 늘려야 하므로, 스택용으로 약 1.2G를 남겨 둔다.
앱이 루프백에만 바인딩돼 있어 외부에서 접근할 수 없던 것을 nginx로 연다.
80 포트를 받아 gamss 네트워크의 app:8080 으로 프록시한다.

앱 컨테이너는 배포마다 재생성되며 IP가 바뀌는데, proxy_pass 에 이름을
그대로 쓰면 nginx가 기동 시점 IP를 캐시해 재배포 후 502가 난다.
Docker 내장 DNS를 resolver로 두고 변수로 넘겨 매번 다시 해석하게 했다.

actuator는 외부에 노출하지 않는다. LLM 응답을 고려해 프록시 타임아웃은
120초로 잡았다. 도메인이 정해지면 server_name 과 443 블록을 추가한다.
이미지 태그에 브랜치명을 쓰는데 Docker 태그는 슬래시를 허용하지 않는다.
deploy job에만 가드가 있어서, workflow_dispatch로 feat/x 같은 브랜치에서
실행하면 빌드를 전부 끝낸 뒤 push 단계에서 invalid reference format 으로
죽는다. build-and-push 에도 같은 가드를 걸어 아예 시작하지 않게 한다.
ci.yml 과 image.yml 이 각각 push 에 반응해 병렬로 돌아서, 테스트가
깨져도 배포가 그대로 나가고 있었다.

ci.yml 을 workflow_call 로 열고 Build & Deploy 가 호출하게 한다.
push 트리거는 제거한다 — 남겨두면 테스트가 두 번 돌 뿐 아니라
배포를 막지 못하는 문제가 그대로다.

concurrency 그룹은 배포·롤백이 한 환경에서 겹치지 않도록 deploy-{환경}
으로 통일하고, cancel-in-progress 를 끈다. SSH로 원격 상태를 바꾸는
중에 취소당하면 .env 만 갱신되고 컨테이너는 그대로인 상태가 남는다.
배포는 성공했으나 버그가 발견된 경우 이전 이미지 태그로 되돌린다.
헬스체크 실패로 인한 롤백은 배포 중 deploy-app.sh 가 이미 처리하므로,
이 워크플로는 그 이후에 사람이 판단해 되돌리는 경로를 담당한다.

서버에 있는 deploy-app.sh 를 재사용해 헬스체크·자동복구 동작을 배포와
동일하게 가져간다. 태그가 대상 환경 접두사와 다르면 실행 전에 막아
prod 에 dev 이미지를 올리는 사고를 방지한다.
@github-actions

github-actions Bot commented Jul 18, 2026

Copy link
Copy Markdown

Test Results

156 tests  +1   156 ✅ +1   58s ⏱️ -2s
 31 suites +1     0 💤 ±0 
 31 files   +1     0 ❌ ±0 

Results for commit 52343ee. ± Comparison against base commit 08ab61c.

♻️ This comment has been updated with latest results.

@github-actions

github-actions Bot commented Jul 18, 2026

Copy link
Copy Markdown

Test Coverage

Overall Project 80.42% 🍏
Files changed 100% 🍏

File Coverage
SecurityConfig.kt 100% 🍏

dev/prod 에서 client-ids 가 비면 부팅을 실패시키던 것을, 경고 로그만 남기고
부팅은 계속하도록 바꾼다. client-ids 발급 전에 배포 파이프라인을 검증할 수
있게 하기 위함이다.

client-ids 가 비어도 aud 검증은 여전히 fail-closed 라, 소셜 로그인은 안전하게
막힌 채 서버만 뜬다. 설정 누락은 기동 시점 경고로 드러난다(배포 전 필수 설정).
# Conflicts:
#	src/main/kotlin/com/nexters/gamss/auth/oauth/OAuthClientIdsValidator.kt
#	src/test/kotlin/com/nexters/gamss/auth/oauth/OAuthClientIdsValidatorTest.kt
Firebase 전환(#10)으로 앱이 더는 이 값을 읽지 않는다. CD의 .env 생성부와
docker-compose(dev·prod)에서 주입하던 죽은 설정을 정리한다. 앱이 실제로 읽는
env(DB_PASSWORD·JWT_SECRET 등)만 남긴다.
@theminjunchoi

Copy link
Copy Markdown
Collaborator Author

@coderabbitai 리뷰해봐

@coderabbitai

coderabbitai Bot commented Jul 20, 2026

Copy link
Copy Markdown

@theminjunchoi 변경 사항을 리뷰하겠습니다. 배포 스크립트의 실패·롤백 경로, 환경별 시크릿 격리, 컨테이너 네트워킹 및 운영상 복구 가능성을 중점적으로 확인하겠습니다.

✅ Action performed

Review finished.

Note: CodeRabbit is an incremental review system and does not re-review already reviewed commits. This command is applicable only when automatic reviews are paused.

@coderabbitai

coderabbitai Bot commented Jul 20, 2026

Copy link
Copy Markdown

Review Change Stack

Caution

Review failed

The pull request is closed.

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: ASSERTIVE

Plan: Pro

Run ID: 51b36746-7359-47a7-87ad-9210555b4075

📥 Commits

Reviewing files that changed from the base of the PR and between c7f849d and 52343ee.

📒 Files selected for processing (5)
  • .github/scripts/deploy-app.sh
  • .github/workflows/image.yml
  • .github/workflows/rollback.yml
  • build.gradle.kts
  • src/main/resources/application.yml

Walkthrough

Docker 멀티 스테이지 이미지와 dev/prod Compose 환경을 추가하고, Actuator 헬스체크를 공개 경로로 구성했습니다. GitHub Actions에서 GHCR 이미지 빌드·푸시, SSH 배포, 헬스체크 기반 롤백 및 수동 롤백을 수행하도록 변경했습니다.

Changes

배포 플랫폼 및 자동화

Layer / File(s) Summary
애플리케이션 이미지와 헬스체크 계약
.dockerignore, Dockerfile, build.gradle.kts, src/main/..., src/test/...
Actuator health 엔드포인트와 환경별 데이터소스 설정을 추가하고, 인증 없는 200 UP 응답을 테스트합니다. Dockerfile은 테스트를 제외한 boot JAR 빌드와 비루트 JRE 실행을 구성합니다.
환경별 서버 구성과 프록시
deploy/dev/docker-compose.yml, deploy/prod/docker-compose.yml, deploy/nginx/conf/gamss.conf, deploy/setup-server.sh
app, nginx, MySQL 컨테이너와 영속 볼륨·전용 네트워크를 정의하고, nginx 리버스 프록시 및 서버 초기화 절차를 추가합니다.
배포 및 실패 롤백 실행
.github/scripts/deploy-app.sh
이미지 태그 갱신, pull, Compose 재기동, health 폴링, nginx 설정 검사·reload, 실패 시 이전 태그 롤백을 수행합니다.
빌드·배포·수동 롤백 워크플로
.github/workflows/ci.yml, .github/workflows/image.yml, .github/workflows/rollback.yml
CI를 재사용 워크플로로 전환하고, GHCR 이미지 빌드·푸시와 환경별 SSH 배포 및 수동 롤백을 추가합니다. 배포 결과는 작업 요약에 기록됩니다.

Estimated code review effort: 4 (Complex) | ~60 minutes

Sequence Diagram(s)

sequenceDiagram
  participant GitHubActions
  participant GHCR
  participant SSHServer
  participant DeployScript
  participant DockerCompose
  participant App
  participant Nginx
  GitHubActions->>GHCR: 이미지 빌드 및 태그 push
  GitHubActions->>SSHServer: Compose, nginx 설정, env, 스크립트 전송
  SSHServer->>DeployScript: 이미지 태그로 배포 실행
  DeployScript->>DockerCompose: app 이미지 pull 및 재기동
  DeployScript->>App: /actuator/health 확인
  DeployScript->>Nginx: 설정 검사 후 reload
  DeployScript->>DockerCompose: 실패 시 이전 이미지 태그로 app 롤백
Loading

Suggested reviewers: kite707

🚥 Pre-merge checks | ✅ 3 | ❌ 2

❌ Failed checks (2 warnings)

Check name Status Explanation Resolution
Linked Issues check ⚠️ Warning 핵심 CD·배포 구성은 구현됐지만, 완료 조건인 HTTPS·도메인 적용과 Swagger 접근 검증은 아직 확인되지 않습니다. certbot/443 설정과 도메인 연결을 추가하고, dev·prod에서 /swagger-ui.html 접근 검증을 포함하세요.,
Docstring Coverage ⚠️ Warning Docstring coverage is 0.00% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (3 passed)
Check name Status Explanation
Out of Scope Changes check ✅ Passed 배포 자동화, 이미지 빌드, 헬스체크, 롤백, 설정 정리는 모두 PR 목적과 이슈 범위 안에 있습니다.
Title check ✅ Passed 배포 환경 구축과 CD 파이프라인 추가라는 핵심 변경을 짧고 명확하게 잘 요약했습니다.
Description check ✅ Passed 필수 섹션인 연관 이슈, 개요, 주요 변경사항, API·DB 영향, 리뷰 포인트가 대부분 충실히 채워졌습니다.
✨ 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/7-deployment

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

🤖 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 @.github/scripts/deploy-app.sh:
- Around line 79-88: Wrap the docker compose up -d commands in the main
deployment flow and rollback() with conditional failure handling compatible with
set -e. Preserve the existing behavior that a main startup failure invokes
rollback(), while rollback() continues to wait_for_health and emit its failure
log instead of terminating the script immediately. Follow the existing guarded
docker compose pull app pattern.

In @.github/workflows/image.yml:
- Around line 18-20: Lower the workflow-level packages permission to read in
.github/workflows/image.yml at lines 18-20, then add an explicit contents: read
and packages: write permission block to the build-and-push job only. Also lower
the workflow-level packages permission to read in .github/workflows/rollback.yml
at lines 27-29; the rollback job needs no job-level override.
- Around line 42-43: Update both Checkout steps in the workflow to disable
credential persistence by explicitly setting persist-credentials to false, and
pin each actions/checkout reference to an immutable commit SHA instead of the
mutable `@v4` tag.
- Around line 54-64: Pin every third-party action to a full commit SHA instead
of a mutable tag: update docker/setup-buildx-action, docker/login-action, and
docker/build-push-action in .github/workflows/image.yml lines 54-64;
appleboy/scp-action at line 98 and appleboy/ssh-action at line 108 in
.github/workflows/image.yml; and appleboy/ssh-action at line 51 in
.github/workflows/rollback.yml. Preserve each action’s existing behavior and
configuration.
- Around line 87-96: Update the “Create .env” step to pass DB_PASSWORD,
DB_ROOT_PASSWORD, and JWT_SECRET through the step’s env configuration, then
reference them as shell variables inside the heredoc instead of interpolating
GitHub secret expressions in run. Preserve the existing .env keys and quoted
heredoc behavior.

In @.github/workflows/rollback.yml:
- Around line 78-88: Rollback Summary에서 자유 형식 입력값이 스크립트에 직접 보간되지 않도록 수정하세요.
`Rollback Summary` 단계에 `env`로 `IMAGE_TAG`, `ENVIRONMENT`, `ACTOR`, `JOB_STATUS`를
전달하고, `run` 블록의 요약 출력에서는 `${{ ... }}` 대신 셸 변수(`"${IMAGE_TAG}"` 등)를 사용하세요.

In `@deploy/dev/docker-compose.yml`:
- Around line 53-57: Update the healthcheck test in
deploy/dev/docker-compose.yml lines 53-57 and deploy/prod/docker-compose.yml
lines 53-57 to use CMD-SHELL and pass the root credentials via
MYSQL_ROOT_PASSWORD, preserving the existing host and healthcheck timing
settings.

In `@deploy/nginx/conf/gamss.conf`:
- Around line 21-24: Update the proxying logic in the root location and the
nearby actuator protection so normalized paths cannot bypass the /actuator
restriction; do not rely on passing $request_uri unchanged. Add an early
rejection for traversal forms including ../ and encoded dot-segments before
proxying, while preserving normal request forwarding and the existing actuator
block behavior.

In `@deploy/setup-server.sh`:
- Line 33: Replace the direct curl-to-shell execution in the server setup flow
with a safer Docker installation method: preferably configure Docker’s official
APT repository and install through the package manager, or download the
installation script to a file, verify its integrity, then execute it. Preserve
the existing Docker installation behavior without piping remote content directly
to sh.
🪄 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: Path: .coderabbit.yaml

Review profile: ASSERTIVE

Plan: Pro

Run ID: 731a506f-5f47-4a8c-a2f0-f3d649840f59

📥 Commits

Reviewing files that changed from the base of the PR and between 55dadf5 and c7f849d.

📒 Files selected for processing (16)
  • .dockerignore
  • .github/scripts/deploy-app.sh
  • .github/workflows/ci.yml
  • .github/workflows/image.yml
  • .github/workflows/rollback.yml
  • Dockerfile
  • build.gradle.kts
  • deploy/dev/docker-compose.yml
  • deploy/nginx/conf/gamss.conf
  • deploy/prod/docker-compose.yml
  • deploy/setup-server.sh
  • src/main/kotlin/com/nexters/gamss/global/security/SecurityConfig.kt
  • src/main/resources/application-dev.yml
  • src/main/resources/application-prod.yml
  • src/main/resources/application.yml
  • src/test/kotlin/com/nexters/gamss/global/config/ActuatorHealthTest.kt

Comment thread .github/scripts/deploy-app.sh
Comment thread .github/workflows/image.yml Outdated
Comment thread .github/workflows/image.yml
Comment thread .github/workflows/image.yml
Comment thread .github/workflows/image.yml
Comment thread .github/workflows/rollback.yml
Comment thread deploy/dev/docker-compose.yml
Comment thread deploy/nginx/conf/gamss.conf
Comment thread deploy/setup-server.sh
CodeRabbit 리뷰 반영.

- deploy-app.sh: set -e 하에서 `docker compose up -d`가 실패하면 스크립트가
  즉시 종료돼 자동 롤백이 안 되던 것을, pull 과 동일하게 `if !`로 감싼다.
  main은 롤백으로, rollback 내부는 경고 후 반환하도록 처리.
- image.yml·rollback.yml: 워크플로 기본 packages 권한을 write→read 로 낮추고,
  GHCR push 가 필요한 build-and-push job 에만 write 를 부여(최소 권한).
- rollback.yml: 자유 형식 입력(image_tag 등)을 Summary 스크립트에 직접 보간하던
  것을 env 로 받아 셸 변수로 참조(스크립트 인젝션 방지).
@theminjunchoi
theminjunchoi requested a review from kite707 July 20, 2026 07:36

@kite707 kite707 left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

고생하셨습니다!

배포 파이프라인 전체(Dockerfile, dev/prod docker-compose, nginx 리버스 프록시, CD 워크플로, 자동/수동 롤백)를 한 번에 깔끔하게 구성해주셨네요.

컨테이너 재생성 시 IP 캐싱으로 에러가 나는 문제까지 미리 막아두신 점도 배워갑니다!

고생많으셨습니다! 승인할게요!

build.gradle.kts 충돌 해소: Actuator(배포)와 Gemini SDK(LLM) 의존성 양쪽 모두 유지.
application.yml 은 dev 기준 + management(actuator) 블록 병합.
@theminjunchoi
theminjunchoi merged commit 36d11c6 into dev Jul 21, 2026
3 checks passed
@theminjunchoi
theminjunchoi deleted the chore/7-deployment branch July 21, 2026 14:17
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.

[chore] 배포 환경 구축 (가비아 2대 · dev/prod · CD)

2 participants