Skip to content

Conversation

@marso34
Copy link
Member

@marso34 marso34 commented Nov 21, 2025

요약

계층형 jar 도입을 통한 Dockerfile 최적화. 서버 배포 방식 AWS SSM Run Command로 변경

상세 내용

  • 서버 배포 방식 AWS SSM 기반 배포로 변경
  • Docker 변경사항
    • 계층형 jar 도입
    • Docker Hub -> GHCR(GitHub Container Registry) 변경
    • 멀티 아키텍처 빌드 도입

Issue Number

#70

@marso34 marso34 self-assigned this Nov 21, 2025
@marso34 marso34 requested a review from nativegold as a code owner November 21, 2025 13:31
@marso34 marso34 added refactor github_actions Pull requests that update GitHub Actions code labels Nov 21, 2025
@marso34 marso34 linked an issue Nov 21, 2025 that may be closed by this pull request
5 tasks
@claude
Copy link

claude bot commented Nov 21, 2025

Claude finished @marso34's task —— View job


코드 리뷰 완료 ✅

작업 목록

  • 변경된 파일 분석
  • Dockerfile 리뷰 (계층형 JAR 구현)
  • GitHub Actions 워크플로우 리뷰 (AWS SSM 배포)
  • build.gradle 변경사항 리뷰
  • .dockerignore 파일 리뷰
  • 보안 취약점 검토
  • 성능 및 코드 품질 검토
  • 종합 피드백 작성

종합 평가

전반적으로 매우 잘 구현된 리팩토링입니다! 계층형 JAR 도입, GHCR 전환, 멀티 아키텍처 빌드, AWS SSM 배포 방식 변경 모두 현대적인 DevOps 모범 사례를 따르고 있습니다. 👍

✅ 잘된 점

  1. 계층형 JAR 구조 (Dockerfile)

    • 의존성, Spring Boot 로더, 스냅샷 의존성, 애플리케이션을 각각 분리하여 Docker 레이어 캐싱 최적화
    • 코드 변경 시 애플리케이션 레이어만 재빌드되어 빌드 시간 대폭 단축
    • bootJar { layered {} } 설정과 완벽하게 연동
  2. 보안 강화 (Dockerfile)

    • 전용 사용자(springuser) 생성 및 사용으로 root 권한 실행 방지
    • JRE 이미지 사용으로 공격 표면 최소화
    • 멀티 스테이지 빌드로 최종 이미지 크기 최소화
  3. 멀티 아키텍처 지원 (deploy.yml)

    • linux/amd64, linux/arm64 동시 빌드
    • QEMU와 Buildx 적절히 활용
    • 다양한 환경에서 배포 가능
  4. GitHub Actions 캐시 전략 (deploy.yml)

    • cache-from: type=gha + cache-to: type=gha,mode=max
    • 빌드 속도 향상을 위한 최적의 설정
  5. .dockerignore 설정

    • 빌드 컨텍스트에서 불필요한 파일 제외
    • 빌드 속도 향상 및 보안 강화

⚠️ 개선이 필요한 부분

1. 치명적: 배포 실패 감지 불가 (deploy.yml:84-101) 🔴

문제점:

  • aws ssm send-command는 명령을 전송만 하고 실행 결과를 확인하지 않습니다
  • Docker pull 실패, 컨테이너 시작 실패 등이 발생해도 CI/CD는 성공으로 표시됩니다
  • 배포가 실패했는데 모르고 지나갈 수 있는 심각한 문제

영향도: 높음 - 프로덕션 배포 시 치명적인 오류로 이어질 수 있음

인라인 코멘트에 상세한 해결 방안을 제시했습니다. get-command-invocation을 사용하여 배포 성공 여부를 반드시 확인해야 합니다.

2. 중요: 배포 버전 추적 불가 (deploy.yml:87) 🟡

문제점:

  • 현재 dev 태그 고정 사용
  • 어떤 커밋이 배포되었는지 추적 불가
  • 롤백 시 어려움

권장 사항:

  • SHA 태그 사용 (TODO 주석에도 명시됨)
  • 또는 dev, dev-{sha} 두 개 태그 동시 사용

3. 보안: provenance 비활성화 (deploy.yml:66) 🟡

문제점:

  • provenance: false로 설정
  • SLSA 공급망 보안 검증 불가

권장 사항:

  • 멀티 아키텍처 빌드 호환성 문제가 없다면 활성화 권장
  • SBOM도 함께 활성화 고려

4. 성능: JVM 최적화 옵션 부족 (Dockerfile:33) 🟡

문제점:

  • -XX:MaxRAMPercentage=75.0만 설정
  • 컨테이너 환경 최적화 옵션 누락

권장 사항:

  • 인라인 코멘트에 상세 옵션 제시
  • OAuth2, JWT 사용 시 특히 유용한 옵션들

5. 코드 스타일: 불필요한 공백 (Dockerfile:10) 🟢

문제점:

  • 10번 라인 앞 공백

권장 사항:

  • 일관성을 위해 제거

🔍 보안 검토

  1. ✅ 컨테이너 보안

    • 비-root 사용자 실행
    • JRE 이미지 사용
    • 최소 권한 원칙 준수
  2. ✅ 시크릿 관리

    • GitHub Secrets 적절히 사용
    • 환경 변수로 민감 정보 분리
  3. ⚠️ OIDC 인증

    • role-to-assume 사용 - 좋은 선택!
    • IAM 역할의 권한 범위를 최소화했는지 확인 필요

🚀 성능 검토

  1. ✅ Docker 빌드

    • 계층형 JAR로 빌드 시간 최소화
    • GitHub Actions 캐시 활용
    • 의존성 레이어 분리로 캐시 히트율 극대화
  2. ✅ 이미지 크기

    • JRE 사용으로 크기 최소화
    • 멀티 스테이지 빌드 활용
  3. ⚠️ 런타임 성능

    • JVM 옵션 추가 최적화 가능 (인라인 코멘트 참조)

📝 추가 제안

  1. 헬스체크 추가
HEALTHCHECK --interval=30s --timeout=3s --start-period=40s --retries=3 \
  CMD wget --no-verbose --tries=1 --spider http://localhost:8080/actuator/health || exit 1
  1. docker-compose.yml 검토

    • /home/ubuntu/ramble-be/docker-compose.yml의 내용 확인 필요
    • 환경 변수, 볼륨, 네트워크 설정 점검 필요
  2. 모니터링 및 알림

    • 배포 실패 시 Slack/Discord 알림 연동 고려
    • CloudWatch 로그 그룹 설정 확인
  3. 롤백 전략

    • SHA 태그 사용 시 이전 버전으로 쉽게 롤백 가능
    • 롤백 워크플로우 추가 고려

🎯 우선순위별 조치사항

🔴 높음 (즉시 수정 권장)

  1. SSM 명령 실행 결과 확인 로직 추가 (deploy.yml:89-101)

🟡 중간 (조만간 개선 권장)
2. SHA 태그 기반 배포로 전환 (deploy.yml:87)
3. JVM 최적화 옵션 추가 (Dockerfile:33)
4. provenance 활성화 검토 (deploy.yml:66)

🟢 낮음 (선택적)
5. 코드 스타일 수정 (Dockerfile:10)
6. 헬스체크 추가
7. 모니터링 강화


최종 의견

이번 리팩토링은 배포 인프라를 크게 개선한 훌륭한 작업입니다. 특히 계층형 JAR와 멀티 아키텍처 지원은 앞으로의 확장성과 유지보수성을 크게 향상시킬 것입니다.

다만, SSM 명령 실행 결과 확인 로직 추가는 프로덕션 안정성을 위해 꼭 필요합니다. 배포가 실패해도 알 수 없는 현재 상태는 위험하므로, 이 부분만 개선하면 안전하게 머지 가능할 것으로 판단됩니다.

인라인 코멘트에 구체적인 코드 예시를 포함했으니 참고해주세요! 🚀


@claude
Copy link

claude bot commented Nov 22, 2025

Claude finished @marso34's task —— View job


코드 리뷰 완료 ✅

작업 목록

  • 변경된 파일 읽기 및 분석
  • 이전 리뷰 피드백 반영 여부 확인
  • 코드 품질 검토
  • 보안 취약점 검토
  • 성능 분석
  • 종합 리뷰 피드백 작성

종합 평가

이전 리뷰에서 지적된 가장 치명적인 문제(SSM 명령 실행 결과 미확인)가 완벽하게 해결되었습니다! 👏

최신 커밋(2848e06)에서 aws ssm wait command-executedget-command-invocation을 사용하여 배포 성공/실패를 정확히 감지하도록 개선되었고, GitHub Actions Summary에 상세한 결과를 출력하는 훌륭한 구현이 추가되었습니다.

✅ 개선된 점 (이전 리뷰 대비)

  1. 🔴 치명적 문제 해결: SSM 명령 실행 결과 확인 (deploy.yml:109-168)

    • aws ssm wait command-executed 추가로 명령 완료 대기
    • get-command-invocation으로 상태, stdout, stderr 확인
    • 배포 실패 시 워크플로우가 실패로 표시되도록 exit 1 추가
    • GitHub Actions Summary에 상세한 실행 결과 출력
    • 완벽한 구현입니다! 🎉
  2. 코드 가독성 향상

    • 상태별 아이콘 매핑 (declare -A ICONS)
    • 출력 길이 제한으로 Actions 로그 가독성 확보
    • 테이블 형식의 Summary 출력

🎯 현재 상태 평가

1. 코드 품질 ⭐⭐⭐⭐⭐

✅ 매우 우수한 점:

  1. Dockerfile (계층형 JAR)

    • 의존성 레이어 분리가 완벽합니다 (dependencies → spring-boot-loader → snapshot-dependencies → application)
    • 멀티 스테이지 빌드로 최종 이미지 크기 최소화
    • 각 레이어에 적절한 소유권 설정 (--chown=springuser:spring)
    • TODO 주석으로 향후 개선 사항 명시 (Dockerfile:33)
  2. GitHub Actions 워크플로우

    • 명확한 단계 분리 (build-and-pushdeploy-to-ec2)
    • needs 키워드로 의존성 명시
    • 적절한 타임아웃 설정 (10분)
    • concurrency 설정으로 동시 배포 방지
    • if: always() 조건으로 명령 결과를 항상 확인
  3. build.gradle

    • bootJar { layered {} } 설정이 Dockerfile과 완벽 연동
    • 간결하고 명확한 구성
  4. .dockerignore

    • 빌드 컨텍스트 최적화
    • 민감한 파일(.env) 제외
    • 불필요한 파일(.md, .git 등) 제외

⚠️ 개선 가능한 점:

  1. Dockerfile:10 - 불필요한 공백

    # 현재 (10번 라인 앞에 공백 존재)
    
    RUN ./gradlew dependencies --no-daemon
    
    # 권장
    RUN ./gradlew dependencies --no-daemon
    • 영향도: 매우 낮음 (스타일 이슈)
    • 우선순위: 🟢 낮음
  2. deploy.yml:93-95 - sudo -u ubuntu 불필요

    # 현재
    "sudo -u ubuntu docker pull $IMAGE:$TAG"
    
    # 검토 필요
    # SSM Run Command가 ubuntu 사용자로 실행된다면 불필요
    # 다른 사용자(예: ssm-user)로 실행된다면 필요
    • SSM 문서가 기본적으로 어떤 사용자로 실행되는지 확인 필요
    • AWS-RunShellScript는 기본적으로 루트 또는 시스템 사용자로 실행될 수 있음
    • ubuntu 사용자로의 전환이 필요한 경우 현재 구현이 맞음
    • 영향도: 낮음 (동작은 정상일 가능성 높음)
    • 우선순위: 🟢 낮음 (확인 후 필요시 수정)

2. 보안 ⭐⭐⭐⭐½

✅ 우수한 보안 구성:

  1. 컨테이너 보안

    • ✅ 비-root 사용자 실행 (USER springuser)
    • ✅ 전용 사용자 및 그룹 생성
    • ✅ 홈 디렉터리 없는 사용자 (--no-create-home)
    • ✅ 로그인 불가 쉘 (-s /bin/false)
    • ✅ JRE 이미지 사용으로 공격 표면 최소화
  2. 시크릿 관리

    • ✅ GitHub Secrets 적절히 사용
    • ✅ OIDC 기반 AWS 인증 (role-to-assume)
    • ✅ 환경 변수로 민감 정보 분리
    • ✅ .dockerignore에 .env 제외
  3. 이미지 보안

    • ✅ 공식 Eclipse Temurin 이미지 사용
    • ✅ 멀티 스테이지 빌드로 빌드 도구 제외

⚠️ 보안 개선 제안:

  1. provenance 비활성화 (deploy.yml:66)

    • 현재: provenance: false
    • 이유: 멀티 아키텍처 호환성 (작성자 답변 확인됨)
    • 현재 설정이 적절합니다 (안정성 > 보안 검증)
    • 향후 Docker buildx 호환성 개선 시 재검토 권장
    • 우선순위: 🟢 낮음 (현재 설정 유지)
  2. IAM 역할 권한 최소화

    • AWS_GHACTIONS_ROLE의 권한 범위 확인 필요
    • 필요한 최소 권한만 부여 (SSM:SendCommand, SSM:GetCommandInvocation 등)
    • 이는 코드 리뷰 범위 밖이지만, AWS IAM 정책 검토를 권장합니다
    • 우선순위: 🟡 중간
  3. Docker 이미지 스캔 추가 권장

    # 선택적 개선: Trivy 이미지 스캔 추가
    - name: Run Trivy vulnerability scanner
      uses: aquasecurity/trivy-action@master
      with:
        image-ref: ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}:dev
        format: 'sarif'
        output: 'trivy-results.sarif'
    • 우선순위: 🟢 낮음 (선택적)

3. 성능 ⭐⭐⭐⭐

✅ 훌륭한 성능 최적화:

  1. Docker 빌드 성능

    • ✅ GitHub Actions 캐시 활용 (cache-from/to: type=gha)
    • ✅ 계층형 JAR로 의존성 레이어 캐싱
    • .dockerignore로 빌드 컨텍스트 최소화
    • ✅ 멀티 스테이지 빌드로 최종 이미지 크기 감소
  2. 배포 성능

    • --remove-orphans로 불필요한 컨테이너 정리
    • docker image prune -f로 이미지 정리
    • ✅ 적절한 타임아웃 설정 (480초)

⚠️ 성능 개선 제안:

  1. JVM 최적화 옵션 추가 (Dockerfile:33-34)

    # 현재
    ENTRYPOINT ["java", "-XX:MaxRAMPercentage=75.0", "org.springframework.boot.loader.launch.JarLauncher"]
    
    # 권장 (OAuth2, JWT 사용 고려)
    ENTRYPOINT ["java", \
        "-XX:MaxRAMPercentage=75.0", \
        "-XX:InitialRAMPercentage=50.0", \
        "-XX:MinRAMPercentage=25.0", \
        "-XX:+UseContainerSupport", \
        "-XX:+ExitOnOutOfMemoryError", \
        "-Djava.security.egd=file:/dev/./urandom", \
        "org.springframework.boot.loader.launch.JarLauncher"]

    각 옵션 설명:

    • InitialRAMPercentage: 초기 힙 크기 설정으로 시작 시간 단축

    • MinRAMPercentage: 최소 힙 크기 보장

    • UseContainerSupport: 컨테이너 메모리 제한 인식 (Java 11+에서 기본값이지만 명시적 선언)

    • ExitOnOutOfMemoryError: OOM 발생 시 프로세스 종료로 컨테이너 재시작 유도

    • java.security.egd: SecureRandom 엔트로피 소스 최적화 (OAuth2, JWT 서명 시 성능 향상)

    • 영향도: 중간 (시작 시간 개선, OOM 복구 자동화)

    • 우선순위: 🟡 중간

    • 참고: build.gradle에서 OAuth2, JWT 의존성 확인됨

  2. Gradle 데몬 비활성화 트레이드오프

    # 현재 (Dockerfile:10, 14)
    RUN ./gradlew dependencies --no-daemon
    RUN ./gradlew bootJar --no-daemon
    • --no-daemon은 CI/CD 환경에서 권장되는 설정입니다 ✅
    • 각 빌드가 독립적으로 실행되어 깨끗한 상태 보장
    • GitHub Actions 캐시로 충분히 보완됨
    • 현재 설정이 적절합니다

4. 아키텍처 및 설계 ⭐⭐⭐⭐⭐

✅ 모범 사례 준수:

  1. 멀티 아키텍처 지원

    • linux/amd64, linux/arm64 동시 빌드
    • QEMU와 Buildx 적절히 활용
    • 다양한 환경에서 배포 가능성 확보
  2. 컨테이너 레지스트리 전환

    • Docker Hub → GHCR 전환은 좋은 선택
    • GitHub 통합으로 권한 관리 간소화
    • 무료 tier에서 더 나은 성능
  3. 배포 전략

    • AWS SSM Run Command 사용은 보안 그룹 설정 불필요
    • Session Manager와의 통합 가능
    • 명령 실행 히스토리 추적 가능

⚠️ 아키텍처 개선 제안:

  1. 버전 추적 전략 (deploy.yml:52, 89)

    # 현재
    TAG="dev"  # 고정 태그
    
    # 개선 제안 (TODO 주석에도 언급됨)
    # 두 가지 태그 동시 사용
    tags: |
      type=sha,prefix=,format=short
      type=raw,value=dev
    
    # 배포 시 SHA 태그 사용
    TAG="${{ steps.meta.outputs.tags | grep -o '[a-f0-9]\{7\}' | head -1 }}"

    장점:

    • 🔄 특정 커밋으로 롤백 용이
    • 📊 배포 이력 추적 가능
    • 🔒 동시 배포 시 태그 충돌 방지
    • 🐛 문제 발생 시 디버깅 용이

    단점:

    • 이미지 저장 공간 증가 (정기적 정리 필요)

    • 영향도: 중간 (운영 편의성)

    • 우선순위: 🟡 중간

  2. 헬스체크 추가 권장

    # Dockerfile에 추가 권장
    HEALTHCHECK --interval=30s --timeout=3s --start-period=40s --retries=3 \
      CMD wget --no-verbose --tries=1 --spider http://localhost:8080/actuator/health || exit 1

    장점:

    • Docker/Kubernetes가 컨테이너 상태 자동 감지
    • 비정상 컨테이너 자동 재시작
    • docker-compose health check와 연동

    전제조건:

    • Spring Boot Actuator가 활성화되어 있어야 함

    • 포트 8080이 맞는지 확인 필요

    • 우선순위: 🟡 중간

  3. 롤백 워크플로우 추가 고려

    # 선택적: 수동 롤백 워크플로우
    on:
      workflow_dispatch:
        inputs:
          version:
            description: 'SHA or tag to rollback to'
            required: true
    • 우선순위: 🟢 낮음 (선택적)

🎨 코드 스타일 및 가독성

✅ 우수한 점:

  • 명확한 주석 (한글로 의도 명시)
  • TODO 주석으로 향후 개선 사항 명시
  • 일관된 들여쓰기 및 포매팅

⚠️ 미세한 개선점:

  • Dockerfile:10 공백 제거 (언급됨)

📋 추가 확인 필요 사항

  1. docker-compose.yml 내용 확인

    • /home/ubuntu/ramble-be/docker-compose.yml 파일 내용
    • 환경 변수 설정이 적절한지
    • 볼륨 마운트 설정
    • 네트워크 구성
    • 재시작 정책 (restart: unless-stopped 권장)
  2. EC2 인스턴스 설정

    • SSM Agent 설치 및 실행 상태
    • IAM 인스턴스 프로필 설정
    • Docker 및 docker-compose 설치 상태
    • /home/ubuntu/ramble-be 디렉터리 권한
  3. 모니터링 및 로깅

    • CloudWatch Logs 설정 확인
    • 애플리케이션 로그 수집 방법
    • 알림 설정 (배포 실패 시 Slack/Discord 등)

🎯 우선순위별 조치 사항

🔴 높음 (즉시 조치 권장)

  • 없음 - 이전 리뷰의 치명적 문제가 모두 해결되었습니다! 🎉

🟡 중간 (조만간 개선 권장)

  1. SHA 태그 기반 배포로 전환 (deploy.yml:89) - 롤백 용이성
  2. JVM 최적화 옵션 추가 (Dockerfile:34) - 성능 및 안정성
  3. IAM 역할 권한 최소화 확인 - 보안 강화
  4. 헬스체크 추가 (Dockerfile) - 자동 복구
  5. docker-compose.yml 내용 검토 - 배포 안정성

🟢 낮음 (선택적)

  1. Dockerfile 공백 제거 (Dockerfile:10) - 코드 스타일
  2. sudo -u ubuntu 필요성 확인 (deploy.yml:93-95) - 최적화
  3. provenance 재검토 (향후, 도구 호환성 개선 시)
  4. Trivy 이미지 스캔 추가 - 보안 강화
  5. 롤백 워크플로우 추가 - 운영 편의성

🏆 최종 의견

이번 PR은 프로덕션 배포 준비가 거의 완료된 상태입니다! 🚀

주요 성과:

  • ✅ 이전 리뷰의 치명적 문제(SSM 결과 확인) 완벽히 해결
  • ✅ 계층형 JAR로 빌드/배포 성능 최적화
  • ✅ 멀티 아키텍처 지원으로 확장성 확보
  • ✅ 보안 모범 사례 준수
  • ✅ 상세한 배포 로그 및 모니터링

현재 머지 가능 여부:

  • ✅ 머지 가능 - 모든 치명적 이슈가 해결되었습니다
  • 중간 우선순위 항목들은 머지 후 점진적으로 개선 가능합니다

특히 칭찬할 점:

  1. SSM 명령 실행 결과 확인 로직이 매우 잘 구현되었습니다
    • aws ssm wait + get-command-invocation 조합
    • GitHub Actions Summary에 상세 출력
    • 적절한 에러 처리 및 exit code 설정
  2. 계층형 JAR 구조가 완벽하게 구현되었습니다
  3. 보안 측면에서 비-root 사용자 실행 등 모범 사례를 잘 따랐습니다

다음 단계 제안:

  1. 이 PR을 머지합니다
  2. 개발 환경에서 배포 테스트를 진행하며 모니터링합니다
  3. SHA 태그 기반 배포로 전환하는 follow-up PR을 생성합니다
  4. JVM 옵션 최적화 및 헬스체크를 추가하는 개선 작업을 진행합니다

훌륭한 리팩토링 작업이었습니다! 🎉


@marso34 marso34 merged commit 291ec16 into main Nov 25, 2025
4 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

github_actions Pull requests that update GitHub Actions code refactor

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[Refactor] BE 개발 서버 배포 방식을 SSH에서 AWS SSM으로 변경

3 participants