[SOU-420] blue/green docker-compose 구성 추가#209
Conversation
요약Blue/Green 배포를 위한 두 개의 새로운 Docker Compose 구성 파일이 추가되었습니다. 각 파일은 서로 다른 포트 매핑으로 백엔드 서비스를 정의합니다. 변경 사항
예상 코드 리뷰 노력🎯 2 (Simple) | ⏱️ ~8 분 🚥 Pre-merge checks | ✅ 3✅ Passed checks (3 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. ✨ Finishing Touches🧪 Generate unit tests (beta)
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. Comment |
There was a problem hiding this comment.
💡 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 |
There was a problem hiding this comment.
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 👍 / 👎.
There was a problem hiding this comment.
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.
| 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 | ||
|
|
There was a problem hiding this comment.
🧩 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 -nRepository: 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 -nRepository: 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: alwaysdocker-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.
| 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 |
There was a problem hiding this comment.
🧩 Analysis chain
🏁 Script executed:
find deploy -name "docker-compose*.yaml" -o -name "docker-compose*.yml" 2>/dev/null | head -20Repository: 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.yamlRepository: 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 -20Repository: souzip/souzip-api
Length of output: 328
🏁 Script executed:
find . -path "./.git" -prune -o -name "*.sh" -type f -print | grep -i deploy | head -10Repository: souzip/souzip-api
Length of output: 192
🏁 Script executed:
cat deploy/dev/scripts/deploy.shRepository: 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 -10Repository: souzip/souzip-api
Length of output: 43
🏁 Script executed:
find . -path "./.git" -prune -o -type d -name ".github" -printRepository: 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 -100Repository: souzip/souzip-api
Length of output: 2288
🏁 Script executed:
cat .github/workflows/*.yml 2>/dev/null | head -200Repository: 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.
| 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.
Summary by CodeRabbit
릴리스 노트