refactor: prod/stage 환경 nginx 블루/그린 배포 방식 도입#756
Conversation
Walkthrough이번 PR은 dev/prod 두 환경 모두에 Blue/Green 무중단 배포 방식을 도입합니다.
Estimated code review effort🎯 4 (Complex) | ⏱️ ~50 minutes Suggested reviewers
🚥 Pre-merge checks | ✅ 5✅ Passed checks (5 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. ✨ Finishing Touches📝 Generate docstrings
🧪 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 |
2207f68 to
3934f41
Compare
There was a problem hiding this comment.
Actionable comments posted: 1
🧹 Nitpick comments (2)
.github/workflows/prod-cd.yml (1)
62-67: ⚡ Quick winRelease 태그 및 수동 입력 태그의 command injection 위험성
정적 분석 도구가
${{ github.ref_name }}과${{ inputs.tag_name }}에서 템플릿 인젝션을 경고하고 있어요.
- Release 태그: 악의적인 태그명(예:
v1.0.0$(whoami))이 생성될 경우 셸 명령어 실행 위험이 있어요.- 수동 입력: workflow_dispatch 권한이 있는 사용자가 악의적인 입력을 할 수 있어요.
다만 실제 위험도는 낮습니다:
- Docker 태그 명명 규칙이 특수문자를 제한합니다.
- Release 생성 권한은 신뢰할 수 있는 사용자로 제한되어야 합니다.
🔐 환경 변수를 통한 안전한 전달 방식 제안
- name: Define image name and tag id: image_meta + env: + REF_NAME: ${{ github.ref_name }} + INPUT_TAG: ${{ inputs.tag_name }} run: | OWNER_LOWERCASE=$(echo "${{ github.repository_owner }}" | tr '[:upper:]' '[:lower:]') # Trigger가 Release인 경우: Release의 Tag Name (예: v1.0.0) 사용 if [ "${{ github.event_name }}" == "release" ]; then - IMAGE_TAG="${{ github.ref_name }}" + IMAGE_TAG="${REF_NAME}" # Trigger가 수동(workflow_dispatch)인 경우: 입력받은 tag_name 사용 else - IMAGE_TAG="${{ inputs.tag_name }}" + IMAGE_TAG="${INPUT_TAG}" fi환경 변수로 전달하면 셸 문맥에서의 직접 확장을 방지할 수 있어요.
🤖 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/prod-cd.yml around lines 62 - 67, The IMAGE_TAG assignment in the conditional block uses direct GitHub context variable expansion (`${{ github.ref_name }}` and `${{ inputs.tag_name }}`) within the shell script, which poses a potential command injection risk through template injection. Refactor this to use environment variables that are set before the shell command runs, rather than expanding the GitHub context variables directly within the shell script itself. This will prevent shell metacharacters from being interpreted as commands while still correctly capturing the tag value from either the release event or the manual workflow input.Source: Linters/SAST tools
.github/workflows/dev-cd.yml (1)
122-128: 💤 Low value슬롯 판별 로직의 fallback 값 "8081" 일관성 개선
두 워크플로우 모두
upstream.conf를 읽지 못할 때 fallback 값으로"8081"(management 포트)을 사용하고 있어요. 이 값은 APP 포트(8080/9080)와 혼동될 수 있습니다.
.github/workflows/dev-cd.yml#L122-L128: fallback을"9080"으로 변경하여 "green active → blue 배포" 의도를 명확히.github/workflows/prod-cd.yml#L138-L144: dev와 동일하게 fallback 값 수정🤖 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/dev-cd.yml around lines 122 - 128, The fallback value used when upstream.conf cannot be read is currently "8081" (a management port) in both workflow files, which creates confusion about which application slot is active. In `.github/workflows/dev-cd.yml` at lines 122-128, change the fallback value in the UPSTREAM_PORT grep command from "8081" to "9080" to clarify the default assumption that green slot is active and blue will be deployed to. Apply the same change in `.github/workflows/prod-cd.yml` at lines 138-144 to maintain consistency across both workflows.
🤖 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/workflows/dev-cd.yml:
- Around line 143-145: The docker login command in the GHCR authentication step
may be recorded in the remote server's shell history when executed via SSH,
creating a security risk where the GitHub token could be exposed. Verify and
configure the remote server's shell history settings to prevent sensitive
commands from being recorded by checking the HISTCONTROL and HISTFILE
environment variables, and configure them appropriately (such as setting
HISTCONTROL=ignorespace or HISTFILE=/dev/null) before executing the docker login
command. Alternatively, ensure the command is run with history expansion
disabled or use a secure authentication method that doesn't rely on piping
credentials through shell commands.
---
Nitpick comments:
In @.github/workflows/dev-cd.yml:
- Around line 122-128: The fallback value used when upstream.conf cannot be read
is currently "8081" (a management port) in both workflow files, which creates
confusion about which application slot is active. In
`.github/workflows/dev-cd.yml` at lines 122-128, change the fallback value in
the UPSTREAM_PORT grep command from "8081" to "9080" to clarify the default
assumption that green slot is active and blue will be deployed to. Apply the
same change in `.github/workflows/prod-cd.yml` at lines 138-144 to maintain
consistency across both workflows.
In @.github/workflows/prod-cd.yml:
- Around line 62-67: The IMAGE_TAG assignment in the conditional block uses
direct GitHub context variable expansion (`${{ github.ref_name }}` and `${{
inputs.tag_name }}`) within the shell script, which poses a potential command
injection risk through template injection. Refactor this to use environment
variables that are set before the shell command runs, rather than expanding the
GitHub context variables directly within the shell script itself. This will
prevent shell metacharacters from being interpreted as commands while still
correctly capturing the tag value from either the release event or the manual
workflow input.
🪄 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: Repository UI
Review profile: CHILL
Plan: Pro
Run ID: 5203ee5a-31e7-41df-8f0f-237e94da7a4f
📒 Files selected for processing (5)
.github/workflows/dev-cd.yml.github/workflows/prod-cd.ymldocker-compose.dev.ymldocker-compose.prod.ymlsrc/main/resources/application.yml
There was a problem hiding this comment.
Caution
Inline review comments failed to post. This is likely due to GitHub's internal server error or limits when posting large numbers of comments. If you are seeing this consistently it is likely a permissions issue. Please check "Moderation" -> "Code review limits" under your organization settings.
Actionable comments posted: 1
🧹 Nitpick comments (2)
.github/workflows/prod-cd.yml (1)
62-67: ⚡ Quick winRelease 태그 및 수동 입력 태그의 command injection 위험성
정적 분석 도구가
${{ github.ref_name }}과${{ inputs.tag_name }}에서 템플릿 인젝션을 경고하고 있어요.
- Release 태그: 악의적인 태그명(예:
v1.0.0$(whoami))이 생성될 경우 셸 명령어 실행 위험이 있어요.- 수동 입력: workflow_dispatch 권한이 있는 사용자가 악의적인 입력을 할 수 있어요.
다만 실제 위험도는 낮습니다:
- Docker 태그 명명 규칙이 특수문자를 제한합니다.
- Release 생성 권한은 신뢰할 수 있는 사용자로 제한되어야 합니다.
🔐 환경 변수를 통한 안전한 전달 방식 제안
- name: Define image name and tag id: image_meta + env: + REF_NAME: ${{ github.ref_name }} + INPUT_TAG: ${{ inputs.tag_name }} run: | OWNER_LOWERCASE=$(echo "${{ github.repository_owner }}" | tr '[:upper:]' '[:lower:]') # Trigger가 Release인 경우: Release의 Tag Name (예: v1.0.0) 사용 if [ "${{ github.event_name }}" == "release" ]; then - IMAGE_TAG="${{ github.ref_name }}" + IMAGE_TAG="${REF_NAME}" # Trigger가 수동(workflow_dispatch)인 경우: 입력받은 tag_name 사용 else - IMAGE_TAG="${{ inputs.tag_name }}" + IMAGE_TAG="${INPUT_TAG}" fi환경 변수로 전달하면 셸 문맥에서의 직접 확장을 방지할 수 있어요.
🤖 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/prod-cd.yml around lines 62 - 67, The IMAGE_TAG assignment in the conditional block uses direct GitHub context variable expansion (`${{ github.ref_name }}` and `${{ inputs.tag_name }}`) within the shell script, which poses a potential command injection risk through template injection. Refactor this to use environment variables that are set before the shell command runs, rather than expanding the GitHub context variables directly within the shell script itself. This will prevent shell metacharacters from being interpreted as commands while still correctly capturing the tag value from either the release event or the manual workflow input.Source: Linters/SAST tools
.github/workflows/dev-cd.yml (1)
122-128: 💤 Low value슬롯 판별 로직의 fallback 값 "8081" 일관성 개선
두 워크플로우 모두
upstream.conf를 읽지 못할 때 fallback 값으로"8081"(management 포트)을 사용하고 있어요. 이 값은 APP 포트(8080/9080)와 혼동될 수 있습니다.
.github/workflows/dev-cd.yml#L122-L128: fallback을"9080"으로 변경하여 "green active → blue 배포" 의도를 명확히.github/workflows/prod-cd.yml#L138-L144: dev와 동일하게 fallback 값 수정🤖 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/dev-cd.yml around lines 122 - 128, The fallback value used when upstream.conf cannot be read is currently "8081" (a management port) in both workflow files, which creates confusion about which application slot is active. In `.github/workflows/dev-cd.yml` at lines 122-128, change the fallback value in the UPSTREAM_PORT grep command from "8081" to "9080" to clarify the default assumption that green slot is active and blue will be deployed to. Apply the same change in `.github/workflows/prod-cd.yml` at lines 138-144 to maintain consistency across both workflows.
🤖 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/workflows/dev-cd.yml:
- Around line 143-145: The docker login command in the GHCR authentication step
may be recorded in the remote server's shell history when executed via SSH,
creating a security risk where the GitHub token could be exposed. Verify and
configure the remote server's shell history settings to prevent sensitive
commands from being recorded by checking the HISTCONTROL and HISTFILE
environment variables, and configure them appropriately (such as setting
HISTCONTROL=ignorespace or HISTFILE=/dev/null) before executing the docker login
command. Alternatively, ensure the command is run with history expansion
disabled or use a secure authentication method that doesn't rely on piping
credentials through shell commands.
---
Nitpick comments:
In @.github/workflows/dev-cd.yml:
- Around line 122-128: The fallback value used when upstream.conf cannot be read
is currently "8081" (a management port) in both workflow files, which creates
confusion about which application slot is active. In
`.github/workflows/dev-cd.yml` at lines 122-128, change the fallback value in
the UPSTREAM_PORT grep command from "8081" to "9080" to clarify the default
assumption that green slot is active and blue will be deployed to. Apply the
same change in `.github/workflows/prod-cd.yml` at lines 138-144 to maintain
consistency across both workflows.
In @.github/workflows/prod-cd.yml:
- Around line 62-67: The IMAGE_TAG assignment in the conditional block uses
direct GitHub context variable expansion (`${{ github.ref_name }}` and `${{
inputs.tag_name }}`) within the shell script, which poses a potential command
injection risk through template injection. Refactor this to use environment
variables that are set before the shell command runs, rather than expanding the
GitHub context variables directly within the shell script itself. This will
prevent shell metacharacters from being interpreted as commands while still
correctly capturing the tag value from either the release event or the manual
workflow input.
🪄 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: Repository UI
Review profile: CHILL
Plan: Pro
Run ID: 5203ee5a-31e7-41df-8f0f-237e94da7a4f
📒 Files selected for processing (5)
.github/workflows/dev-cd.yml.github/workflows/prod-cd.ymldocker-compose.dev.ymldocker-compose.prod.ymlsrc/main/resources/application.yml
🛑 Comments failed to post (1)
.github/workflows/dev-cd.yml (1)
143-145:
⚠️ Potential issue | 🟡 Minor🧩 Analysis chain
🏁 Script executed:
#!/bin/bash # 원격 서버에서 shell history가 비활성화되어 있는지, # 또는 HISTCONTROL 설정이 민감한 명령어를 제외하는지 확인이 필요합니다. # 이 스크립트는 일반적인 확인 사항을 제시합니다. echo "GitHub Actions의 기본 동작:" echo "1. secrets.* 값은 로그에서 자동 마스킹됨" echo "2. SSH 세션 내 명령어는 원격 서버의 history 설정에 따름" echo "" echo "권장 사항: 원격 서버에서 HISTCONTROL=ignorespace 또는 HISTFILE=/dev/null 설정 확인"Repository: solid-connection/solid-connect-server
Length of output: 240
🏁 Script executed:
cat -n .github/workflows/dev-cd.yml | sed -n '130,160p'Repository: solid-connection/solid-connect-server
Length of output: 1962
🏁 Script executed:
# Check for any deployment scripts or configurations that handle shell history find . -type f \( -name "*.sh" -o -name "*.bash" -o -name "*.yml" -o -name "*.yaml" \) | xargs grep -l "HISTCONTROL\|HISTFILE\|history" 2>/dev/null | head -20Repository: solid-connection/solid-connect-server
Length of output: 63
🏁 Script executed:
# Check the full deploy job context and permissions grep -A 50 "deploy:" .github/workflows/dev-cd.yml | head -70Repository: solid-connection/solid-connect-server
Length of output: 2259
GHCR 인증 시 원격 서버 shell history 보안 고려가 필요합니다.
현재 구현은 표준적인 방식이지만, 보안 관점에서 다음 사항들을 검토해 보세요:
토큰 노출 경로 확인
echo ... | docker login명령은 GitHub Actions에서 마스킹되지만, SSH를 통해 원격 서버에서 실행되므로 서버의 shell history에 기록될 수 있습니다.원격 서버 설정 확인
- 원격 서버의
HISTCONTROL또는HISTFILE설정을 확인해 토큰을 포함한 민감한 명령어가 history에 남지 않도록 해야 합니다.- 예:
HISTCONTROL=ignorespace또는HISTFILE=/dev/null설정 권장권한 범위 검증
- 현재 deploy job의
permissions: { packages: read }는 GHCR 접근에 충분히 제한적이고 적절합니다.추가 검토는 원격 인프라 설정에 따라 결정하시면 됩니다.
🧰 Tools
🪛 zizmor (1.25.2)
[error] 144-144: code injection via template expansion (template-injection): may expand into attacker-controllable code
(template-injection)
🤖 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/dev-cd.yml around lines 143 - 145, The docker login command in the GHCR authentication step may be recorded in the remote server's shell history when executed via SSH, creating a security risk where the GitHub token could be exposed. Verify and configure the remote server's shell history settings to prevent sensitive commands from being recorded by checking the HISTCONTROL and HISTFILE environment variables, and configure them appropriately (such as setting HISTCONTROL=ignorespace or HISTFILE=/dev/null) before executing the docker login command. Alternatively, ensure the command is run with history expansion disabled or use a secure authentication method that doesn't rely on piping credentials through shell commands.Source: Linters/SAST tools
💡 Codex ReviewWhen ℹ️ About Codex in GitHubCodex has been enabled to automatically review pull requests in this repo. Reviews are triggered when you
If Codex has suggestions, it will comment; otherwise it will react with 👍. When you sign up for Codex through ChatGPT, Codex can also answer questions or update the PR, like "@codex address that feedback". |
관련 이슈
작업 내용
단일 EC2에서 Nginx upstream 전환 방식으로 무중단 Blue/Green 배포를 구현합니다.
Blue/Green 슬롯 구성
docker-compose 슬롯 파라미터화
container_name,SERVER_PORT,MANAGEMENT_SERVER_PORT를 슬롯 변수로 매개변수화dev-cd.yml / prod-cd.yml 배포 흐름
upstream.conf파싱으로 현재 active 슬롯 감지/actuator/health폴링으로 기동 완료 대기 (최대 150초)upstream.conf교체 +nginx -s reload로 트래픽 무중단 전환application.yml
management.endpoints.web.exposure.include에health추가 (헬스체크용)특이 사항
solid-connection-server,solid-connection-dev) 수동 제거 필요 (레거시 컨테이너가 8080/8081 점유)리뷰 요구사항 (선택)