Skip to content

[SOU-420] blue/green docker-compose 구성 추가#209

Merged
bum0w0 merged 1 commit intodevelopfrom
feat/SOU-420-split-blue-green
Mar 2, 2026
Merged

[SOU-420] blue/green docker-compose 구성 추가#209
bum0w0 merged 1 commit intodevelopfrom
feat/SOU-420-split-blue-green

Conversation

@bum0w0
Copy link
Member

@bum0w0 bum0w0 commented Mar 2, 2026

Summary by CodeRabbit

릴리스 노트

  • Chores
    • 블루/그린 배포 방식의 프로덕션 환경 설정 추가: 별도의 백엔드 서비스 인스턴스 구성으로 무중단 배포 지원 및 안정적인 프로덕션 운영 환경 구축

@bum0w0 bum0w0 added ci/cd 빌드, 배포, 워크플로우(파이프라인) 등 CI/CD 설정 변경에 사용합니다. feat 기존 기능을 개선하거나 새로운 기능을 추가하는 경우에 사용합니다. labels Mar 2, 2026
@coderabbitai
Copy link

coderabbitai bot commented Mar 2, 2026

요약

Blue/Green 배포를 위한 두 개의 새로운 Docker Compose 구성 파일이 추가되었습니다. 각 파일은 서로 다른 포트 매핑으로 백엔드 서비스를 정의합니다.

변경 사항

Cohort / File(s) 요약
Blue/Green 배포 설정
deploy/prod/docker-compose.blue.yaml, deploy/prod/docker-compose.green.yaml
Blue와 Green 환경용 Docker Compose 구성 파일 추가. 각 파일은 souzip-api 이미지를 사용하여 서로 다른 포트(Blue: 8081, Green: 8082)로 매핑된 백엔드 서비스를 정의. 공통 환경 변수(SPRING_PROFILES_ACTIVE=prod, TZ=Asia/Seoul)와 항상 재시작되는 정책을 적용하며, souzip-network 외부 네트워크를 사용.

예상 코드 리뷰 노력

🎯 2 (Simple) | ⏱️ ~8 분

🚥 Pre-merge checks | ✅ 3
✅ Passed checks (3 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed PR 제목이 변경사항의 주요 내용을 명확하게 요약하고 있습니다. Blue/green 배포를 위한 docker-compose 파일 추가라는 핵심 변경사항을 정확히 반영합니다.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.

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

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch feat/SOU-420-split-blue-green

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.

Copy link

@chatgpt-codex-connector chatgpt-codex-connector bot left a comment

Choose a reason for hiding this comment

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

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 29ed8d470b

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

services:
backend:
image: asia-northeast3-docker.pkg.dev/souzip-488211/souzip-prod-repo/souzip-api:latest
container_name: souzip-api-blue

Choose a reason for hiding this comment

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

P1 Badge 프로덕션 모니터링 대상 컨테이너명을 일치시키세요

deploy/shared/system-monitor.sh는 prod에서 souzip-api-prod만 조회해 상태를 판단하는데(라인 93~99), 이번 변경으로 생성되는 컨테이너명은 souzip-api-blue/souzip-api-green뿐이라 blue/green 배포를 적용하면 모니터가 항상 컨테이너 다운으로 오탐지하게 됩니다. 이 상태에서는 장애 알림 신뢰도가 깨지고 실제 다운 감지도 어려워지므로, 모니터링 스크립트가 blue/green 이름을 인식하도록 바꾸거나 compose의 container_name을 기존 규칙과 맞춰야 합니다.

Useful? React with 👍 / 👎.

Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 2

🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@deploy/prod/docker-compose.blue.yaml`:
- Around line 4-15: Add a Docker healthcheck to the backend service so
blue/green switchovers wait for a healthy /actuator/health response; update the
backend service (container_name souzip-api-blue) to include a healthcheck that
queries http://localhost:8080/actuator/health with sensible parameters (e.g.,
interval, timeout, retries, start_period) and marks unhealthy on non-200, and
mirror the same healthcheck into the green compose file for its backend service
(only container_name and ports differ) so the orchestrator only routes to ready
instances.
- Line 5: The image line currently pins a mutable tag
"asia-northeast3-docker.pkg.dev/souzip-488211/souzip-prod-repo/souzip-api:latest"
which breaks reproducibility; change it to use an immutable tag or digest
supplied by CI (e.g., replace :latest with :${SOUZIP_API_IMAGE_TAG} or the
digest) and ensure both blue and green manifests consume the same
SOUZIP_API_IMAGE_TAG variable during deployment so the exact same image is
deployed/rolled back; update your CI/CD to generate SOUZIP_API_IMAGE_TAG (commit
SHA or semantic version) and fail the deploy if that variable is missing.

ℹ️ Review info

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 08d2bcd and 29ed8d4.

📒 Files selected for processing (2)
  • deploy/prod/docker-compose.blue.yaml
  • deploy/prod/docker-compose.green.yaml

Comment on lines +4 to +15
backend:
image: asia-northeast3-docker.pkg.dev/souzip-488211/souzip-prod-repo/souzip-api:latest
container_name: souzip-api-blue
ports:
- "8081:8080"
environment:
- SPRING_PROFILES_ACTIVE=prod
- TZ=Asia/Seoul
env_file:
- .env
restart: always

Copy link

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟠 Major

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
set -euo pipefail

echo "=== [1] docker-compose 파일 목록 ==="
find . -name "docker-compose*.yaml" -o -name "docker-compose*.yml" | head -20

echo -e "\n=== [2] docker-compose.blue.yaml 현재 내용 ==="
if [ -f "deploy/prod/docker-compose.blue.yaml" ]; then
  cat -n "deploy/prod/docker-compose.blue.yaml"
else
  echo "파일을 찾을 수 없음"
fi

echo -e "\n=== [3] docker-compose.green.yaml 내용 (비교) ==="
if [ -f "deploy/prod/docker-compose.green.yaml" ]; then
  cat -n "deploy/prod/docker-compose.green.yaml"
fi

echo -e "\n=== [4] Spring Boot application 설정 파일 탐색 ==="
find . -name "application*.properties" -o -name "application*.yml" -o -name "application*.yaml" | head -20

echo -e "\n=== [5] Management/Health 관련 설정 검색 ==="
rg -i "management\." --type=properties --type=yaml -n | head -40

echo -e "\n=== [6] 헬스체크 관련 기존 설정 ==="
rg -i "healthcheck" --type=yaml --type=yml -n

Repository: souzip/souzip-api

Length of output: 1737


🏁 Script executed:

#!/bin/bash
set -euo pipefail

echo "=== [1] application.yaml 내용 ==="
if [ -f "src/main/resources/application.yaml" ]; then
  cat -n "src/main/resources/application.yaml"
fi

echo -e "\n=== [2] application-prod.yaml 내용 ==="
if [ -f "src/main/resources/application-prod.yaml" ]; then
  cat -n "src/main/resources/application-prod.yaml"
fi

echo -e "\n=== [3] 모든 yaml 파일에서 management 설정 검색 ==="
rg "management" --type=yaml -n -A 5

echo -e "\n=== [4] 헬스/health 관련 설정 ==="
rg -i "health|actuator" --type=yaml -n

Repository: souzip/souzip-api

Length of output: 6120


blue/green 전환 안정성을 위해 healthcheck를 추가하세요.

docker-compose.blue.yaml과 docker-compose.green.yaml 모두 컨테이너 준비 상태 확인 설정이 없어서 트래픽 전환 시 비정상 인스턴스로 라우팅될 수 있습니다. 애플리케이션의 /actuator/health 엔드포인트(application-prod.yaml에서 활성화됨)를 활용하여 헬스체크를 구성해야 합니다.

제안 수정안
services:
  backend:
    image: asia-northeast3-docker.pkg.dev/souzip-488211/souzip-prod-repo/souzip-api:latest
    container_name: souzip-api-blue
    ports:
      - "8081:8080"
    environment:
      - SPRING_PROFILES_ACTIVE=prod
      - TZ=Asia/Seoul
    env_file:
      - .env
+   healthcheck:
+     test: ["CMD-SHELL", "wget -qO- http://localhost:8080/actuator/health | grep -q 'UP' || exit 1"]
+     interval: 10s
+     timeout: 3s
+     retries: 5
+     start_period: 30s
    restart: always

docker-compose.green.yaml도 동일하게 적용하세요(container_name과 ports만 다름).

📝 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
backend:
image: asia-northeast3-docker.pkg.dev/souzip-488211/souzip-prod-repo/souzip-api:latest
container_name: souzip-api-blue
ports:
- "8081:8080"
environment:
- SPRING_PROFILES_ACTIVE=prod
- TZ=Asia/Seoul
env_file:
- .env
restart: always
backend:
image: asia-northeast3-docker.pkg.dev/souzip-488211/souzip-prod-repo/souzip-api:latest
container_name: souzip-api-blue
ports:
- "8081:8080"
environment:
- SPRING_PROFILES_ACTIVE=prod
- TZ=Asia/Seoul
env_file:
- .env
healthcheck:
test: ["CMD-SHELL", "wget -qO- http://localhost:8080/actuator/health | grep -q 'UP' || exit 1"]
interval: 10s
timeout: 3s
retries: 5
start_period: 30s
restart: always
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@deploy/prod/docker-compose.blue.yaml` around lines 4 - 15, Add a Docker
healthcheck to the backend service so blue/green switchovers wait for a healthy
/actuator/health response; update the backend service (container_name
souzip-api-blue) to include a healthcheck that queries
http://localhost:8080/actuator/health with sensible parameters (e.g., interval,
timeout, retries, start_period) and marks unhealthy on non-200, and mirror the
same healthcheck into the green compose file for its backend service (only
container_name and ports differ) so the orchestrator only routes to ready
instances.


services:
backend:
image: asia-northeast3-docker.pkg.dev/souzip-488211/souzip-prod-repo/souzip-api:latest
Copy link

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟠 Major

🧩 Analysis chain

🏁 Script executed:

find deploy -name "docker-compose*.yaml" -o -name "docker-compose*.yml" 2>/dev/null | head -20

Repository: souzip/souzip-api

Length of output: 204


🏁 Script executed:

ls -la deploy/prod/ 2>/dev/null || echo "Directory not found"

Repository: souzip/souzip-api

Length of output: 316


🏁 Script executed:

cat deploy/prod/docker-compose.blue.yaml 2>/dev/null || echo "File not found"

Repository: souzip/souzip-api

Length of output: 443


🏁 Script executed:

cat deploy/prod/docker-compose.green.yaml

Repository: souzip/souzip-api

Length of output: 444


🏁 Script executed:

find deploy -name "*.sh" -o -name "*.yml" -o -name "*.yaml" | grep -E "(deploy|script|ci|workflow)" | head -20

Repository: souzip/souzip-api

Length of output: 328


🏁 Script executed:

find . -path "./.git" -prune -o -name "*.sh" -type f -print | grep -i deploy | head -10

Repository: souzip/souzip-api

Length of output: 192


🏁 Script executed:

cat deploy/dev/scripts/deploy.sh

Repository: souzip/souzip-api

Length of output: 3857


🏁 Script executed:

find . -path "./.git" -prune -o -type f \( -name "*.yml" -o -name "*.yaml" \) -print | xargs grep -l "docker-compose" | head -10

Repository: souzip/souzip-api

Length of output: 43


🏁 Script executed:

find . -path "./.git" -prune -o -type d -name ".github" -print

Repository: souzip/souzip-api

Length of output: 70


🏁 Script executed:

ls -la .github/workflows/

Repository: souzip/souzip-api

Length of output: 299


🏁 Script executed:

find .github/workflows -type f \( -name "*.yml" -o -name "*.yaml" \) -exec head -50 {} + | head -100

Repository: souzip/souzip-api

Length of output: 2288


🏁 Script executed:

cat .github/workflows/*.yml 2>/dev/null | head -200

Repository: souzip/souzip-api

Length of output: 43


프로덕션 이미지에 :latest 사용은 배포 재현성을 깨뜨립니다.

blue/green 모두 mutable 태그를 사용 중입니다. 동일한 구성을 재배포할 때마다 서로 다른 이미지를 당길 수 있어, 검증/롤백 안정성을 떨어뜨립니다. immutable 태그(버전, 커밋 SHA 등) 또는 digest로 고정해 주세요.

🔧 제안 수정안
-    image: asia-northeast3-docker.pkg.dev/souzip-488211/souzip-prod-repo/souzip-api:latest
+    image: asia-northeast3-docker.pkg.dev/souzip-488211/souzip-prod-repo/souzip-api:${SOUZIP_API_IMAGE_TAG:?SOUZIP_API_IMAGE_TAG is required}

이 방식을 적용하려면 CI/CD 파이프라인에서 SOUZIP_API_IMAGE_TAG를 (예: git commit SHA, semantic version 등으로) 생성하고 배포 시 전달해야 합니다.

📝 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
image: asia-northeast3-docker.pkg.dev/souzip-488211/souzip-prod-repo/souzip-api:latest
image: asia-northeast3-docker.pkg.dev/souzip-488211/souzip-prod-repo/souzip-api:${SOUZIP_API_IMAGE_TAG:?SOUZIP_API_IMAGE_TAG is required}
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@deploy/prod/docker-compose.blue.yaml` at line 5, The image line currently
pins a mutable tag
"asia-northeast3-docker.pkg.dev/souzip-488211/souzip-prod-repo/souzip-api:latest"
which breaks reproducibility; change it to use an immutable tag or digest
supplied by CI (e.g., replace :latest with :${SOUZIP_API_IMAGE_TAG} or the
digest) and ensure both blue and green manifests consume the same
SOUZIP_API_IMAGE_TAG variable during deployment so the exact same image is
deployed/rolled back; update your CI/CD to generate SOUZIP_API_IMAGE_TAG (commit
SHA or semantic version) and fail the deploy if that variable is missing.

@bum0w0 bum0w0 merged commit c202d35 into develop Mar 2, 2026
4 checks passed
@bum0w0 bum0w0 deleted the feat/SOU-420-split-blue-green branch March 3, 2026 11:13
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

ci/cd 빌드, 배포, 워크플로우(파이프라인) 등 CI/CD 설정 변경에 사용합니다. feat 기존 기능을 개선하거나 새로운 기능을 추가하는 경우에 사용합니다.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant