-
Notifications
You must be signed in to change notification settings - Fork 0
[DEPLOY] ECS+Fargate 기반 Ci Cd 구축 #10
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
|
Warning Rate limit exceeded@oxdjww has exceeded the limit for the number of commits or files that can be reviewed per hour. Please wait 28 minutes and 40 seconds before requesting another review. ⌛ How to resolve this issue?After the wait time has elapsed, a review can be triggered using the We recommend that you space out your commits to avoid hitting the rate limit. 🚦 How do rate limits work?CodeRabbit enforces hourly rate limits for each developer per organization. Our paid plans have higher rate limits than the trial, open-source and free plans. In all cases, we re-allow further reviews after a brief timeout. Please see our FAQ for further information. 📒 Files selected for processing (10)
Walkthrough이번 변경 사항에서는 CI/CD 자동화와 관련된 GitHub Actions 워크플로우 파일이 새롭게 추가되었고, 백엔드 Dockerfile 및 여러 환경설정 파일(application-*.yml)들이 갱신 및 신설되었습니다. 주요 변경점으로는 서버 포트가 8080에서 80으로 일괄 변경되었으며, Swagger 문서의 서버 주소도 이에 맞춰 수정되었습니다. 또한, 공통 엔터티에 Lombok Setter 어노테이션이 추가되었고, 프로덕션 환경을 위한 application-prod.yml이 새롭게 도입되었습니다. CI와 CD 파이프라인은 각각 PR과 main 브랜치 push 시 동작하도록 설정되었습니다. Changes
Sequence Diagram(s)sequenceDiagram
participant Developer
participant GitHub
participant CI Workflow
participant CD Workflow
participant AWS ECR
participant Deploy Script
Developer->>GitHub: PR 생성 또는 main 브랜치 push
alt PR 생성
GitHub->>CI Workflow: CI 워크플로우 트리거
CI Workflow->>CI Workflow: 코드 checkout, JDK/Gradle 설정, 빌드 및 테스트
else main 브랜치 push
GitHub->>CD Workflow: CD 워크플로우 트리거
CD Workflow->>CD Workflow: 코드 checkout, Docker Buildx 설정
CD Workflow->>AWS ECR: 로그인, 이미지 빌드 및 푸시
CD Workflow->>Deploy Script: 배포 스크립트 실행
end
Poem
✨ Finishing Touches
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. 🪧 TipsChatThere are 3 ways to chat with CodeRabbit:
Note: Be mindful of the bot's finite context window. It's strongly recommended to break down tasks such as reading entire modules into smaller chunks. For a focused discussion, use review comments to chat about specific files and their changes, instead of using the PR comments. CodeRabbit Commands (Invoked using PR comments)
Other keywords and placeholders
Documentation and Community
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actionable comments posted: 9
🔭 Outside diff range comments (1)
.github/workflows/cd.yml (1)
32-44:⚠️ Potential issueKafka 연결 설정 누락
CD 워크플로우의env에KAFKA_BOOTSTRAP_SERVERS가 포함되지 않아 프로덕션에서 Kafka 연결이 실패합니다. 워크플로우에 Kafka 시크릿 추가 또는 설정 제거를 검토해주세요.
🧹 Nitpick comments (7)
.github/workflows/ci.yml (1)
1-33: CI 워크플로우 구성이 잘 되어 있습니다만 몇 가지 개선사항을 제안합니다CI 워크플로우가 기본적인 빌드 및 테스트 단계를 잘 구현하고 있습니다. 다만, 효율성과 가시성을 위해 몇 가지 개선점을 제안합니다.
다음과 같은 개선을 고려해보세요:
- Gradle 의존성 캐싱 추가
- 테스트 결과를 아티팩트로 저장
- 코드 품질 분석(SonarQube 등) 추가
name: CI on: pull_request: branches: [ main ] jobs: build-and-test: runs-on: ubuntu-latest defaults: run: working-directory: ./backend steps: - name: Checkout code uses: actions/checkout@v4 - name: Set up JDK 17 uses: actions/setup-java@v4 with: java-version: 17 distribution: temurin + cache: gradle - name: Grant execute permission to Gradle wrapper run: chmod +x gradlew - name: Build with Gradle run: ./gradlew build --no-daemon - name: Run tests run: ./gradlew test + + - name: Save test results + uses: actions/upload-artifact@v4 + if: always() + with: + name: test-results + path: ./backend/build/reports/tests/backend/Dockerfile (1)
10-14: 비-root 사용자 실행 고려
현재 컨테이너가 root 사용자로 실행되어 포트 80 바인딩이 가능하지만, 보안을 위해 비-root 사용자로 실행하도록USER지시어를 추가하는 리팩토링을 제안드립니다.backend/src/main/resources/application-prod.yml (1)
33-33: 파일 끝 개행 추가
YAMLlint 오류 처리: 파일 마지막에 개행(new line)을 추가해주세요.🧰 Tools
🪛 YAMLlint (1.35.1)
[error] 33-33: no new line character at the end of file
(new-line-at-end-of-file)
.github/workflows/cd.yml (4)
3-5: CD 워크플로우 트리거 확인
main브랜치에 대한 push 시 CD가 실행되도록 설정되어 있습니다. 릴리즈 태그나 별도 브랜치에도 배포가 필요하다면 트리거 조건을 확장하세요.
18-20: Amazon ECR 로그인 설정 적절
aws-actions/amazon-ecr-login@v2로 ECR 인증을 처리하는 방식이 안정적입니다. 추가로 OIDC 기반 인증으로 워크플로우 보안을 강화하는 방안도 고려해보세요.
21-25: Docker 빌드 캐시 활용 제안
빌드 속도를 높이기 위해--cache-from옵션 사용 또는actions/cache로 레이어 캐시를 활용하는 구성을 추가하는 것을 권장드립니다.
29-31: 배포 스크립트 실행 권한 확인
./deploy/deploy-prod.sh스크립트가 실행 권한을 갖추고 있는지 확인하세요. 권한 누락 시 워크플로우가 실패할 수 있습니다.
📜 Review details
Configuration used: .coderabbit.yaml
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (9)
.github/workflows/cd.yml(1 hunks).github/workflows/ci.yml(1 hunks)backend/Dockerfile(1 hunks)backend/src/main/java/com/focussu/backend/common/BaseEntity.java(1 hunks)backend/src/main/java/com/focussu/backend/config/SwaggerConfig.java(1 hunks)backend/src/main/java/com/focussu/backend/studyroom/service/StudyRoomQueryService.java(1 hunks)backend/src/main/resources/application-dev.yml(2 hunks)backend/src/main/resources/application-prod.yml(1 hunks)backend/src/main/resources/application.yml(1 hunks)
🧰 Additional context used
🪛 YAMLlint (1.35.1)
backend/src/main/resources/application-dev.yml
[error] 45-45: no new line character at the end of file
(new-line-at-end-of-file)
backend/src/main/resources/application-prod.yml
[error] 33-33: no new line character at the end of file
(new-line-at-end-of-file)
🔇 Additional comments (5)
backend/src/main/java/com/focussu/backend/config/SwaggerConfig.java (1)
19-21:Details
✅ Verification successful
로컬 서버 포트 80 사용에 관한 고려사항
로컬 서버 URL이 포트 8080에서 80으로 변경되었습니다. 포트 80은 표준 HTTP 포트로 URL에 별도 포트 지정이 필요없어 편리하지만, 로컬에서 실행할 때 관리자 권한이 필요할 수 있습니다.
개발 환경에서는 일반적으로 비특권 포트(1024 이상)를 사용하는 것이 권장됩니다. 실제로 애플리케이션이 포트 80으로 구성되어 있는지 확인해보세요:
🏁 Script executed:
#!/bin/bash # application.yml 또는 application-dev.yml에서 서버 포트 설정 확인 echo "로컬 환경 포트 설정 확인:" find backend/src/main/resources -name "application*.yml" -exec grep -l "port:" {} \; -exec grep "port:" {} \;Length of output: 412
SwaggerConfig 포트 설정 일치 확인
- backend/src/main/java/com/focussu/backend/config/SwaggerConfig.java (Lines 19–21)
· .url("http://localhost:80") 사용- backend/src/main/resources/application-dev.yml
· port: 80- backend/src/main/resources/application-prod.yml
· port: 80애플리케이션 설정과 SwaggerConfig의 로컬 서버 포트(80)가 일치하므로 별도 수정은 필요하지 않습니다. 다만 포트 80 사용 시 운영체제에 따라 관리자 권한이 요구될 수 있으니, 팀 개발 환경에서 문제가 없다면 현 상태를 유지하시고, 필요 시 비특권 포트(예: 8080) 사용도 검토해 주세요.
backend/Dockerfile (1)
13-13: 컨테이너 노출 포트 일관성 확인
application-*.yml에서 80 포트를 사용하도록 변경한 것과 일치합니다.backend/src/main/resources/application.yml (1)
3-7: 기본 프로파일 및 시크릿 import 설정 적절
application.yml에서 기본 프로파일을prod로 활성화하고,application-secret.yml을 optional import 하는 패턴은 비밀 정보 관리 관점에서 안전하며 잘 구성되었습니다.backend/src/main/resources/application-dev.yml (1)
3-5: 개발 환경 포트 변경 확인 필요
application-dev.yml의server.port: 80은 로컬 개발 시 root 권한 바인딩 이슈를 발생시킬 수 있습니다. 의도된 설정인지 확인 부탁드립니다.backend/src/main/resources/application-prod.yml (1)
25-27: 프로덕션 포트 설정 확인
server.port를 80으로 설정하여 Dockerfile 및 CI/CD 배포와 일관성이 있습니다.
backend/src/main/java/com/focussu/backend/studyroom/service/StudyRoomQueryService.java
Outdated
Show resolved
Hide resolved
| public StudyRoomCreateResponse getStudyRoom(Long id) { | ||
| // TODO: 예외 커스텀 | ||
| StudyRoom studyRoom = studyRoomRepository.findById(id) | ||
| .orElseThrow(() -> new IllegalArgumentException("존재하지 않는 회원입니다.")); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
🛠️ Refactor suggestion
예외 처리 개선 계획에 대한 제안
TODO 주석이 추가된 것을 확인했습니다. 현재는 IllegalArgumentException을 사용하고 있지만, REST API에 더 적합한 커스텀 예외 처리로 개선하는 것이 좋을 것 같습니다.
다음과 같은 방식으로 개선할 수 있습니다:
- 도메인별 커스텀 예외 클래스 생성 (예:
StudyRoomNotFoundException) @ControllerAdvice를 사용한 글로벌 예외 핸들러 구현- 적절한 HTTP 상태 코드와 응답 형식 표준화
- // TODO: 예외 커스텀
- StudyRoom studyRoom = studyRoomRepository.findById(id)
- .orElseThrow(() -> new IllegalArgumentException("존재하지 않는 회원입니다."));
+ StudyRoom studyRoom = studyRoomRepository.findById(id)
+ .orElseThrow(() -> new StudyRoomNotFoundException(id));📝 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.
| public StudyRoomCreateResponse getStudyRoom(Long id) { | |
| // TODO: 예외 커스텀 | |
| StudyRoom studyRoom = studyRoomRepository.findById(id) | |
| .orElseThrow(() -> new IllegalArgumentException("존재하지 않는 회원입니다.")); | |
| public StudyRoomCreateResponse getStudyRoom(Long id) { | |
| - // TODO: 예외 커스텀 | |
| - StudyRoom studyRoom = studyRoomRepository.findById(id) | |
| - .orElseThrow(() -> new IllegalArgumentException("존재하지 않는 회원입니다.")); | |
| + StudyRoom studyRoom = studyRoomRepository.findById(id) | |
| + .orElseThrow(() -> new StudyRoomNotFoundException(id)); |
| import lombok.Getter; | ||
| import lombok.Setter; | ||
| import org.hibernate.annotations.CreationTimestamp; | ||
| import org.hibernate.annotations.UpdateTimestamp; | ||
|
|
||
| import java.time.LocalDateTime; | ||
|
|
||
| @MappedSuperclass | ||
| @Getter | ||
| @Setter |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
🛠️ Refactor suggestion
Base 엔터티에 @Setter 추가는 재고해 볼 필요가 있습니다
BaseEntity에 @Setter 어노테이션을 추가하면 감사(audit) 필드와 같은 중요 필드에 무분별한 접근이 가능해져 데이터 무결성에 위험을 초래할 수 있습니다.
다음과 같은 접근 방식을 고려해보세요:
- 감사 필드(
createdAt,updatedAt)는 불변으로 유지 isDeleted필드는 전용 메서드(예:markAsDeleted())를 통해서만 변경 가능하도록 제한- 필요한 경우 특정 필드에 대해서만 개별적으로 setter를 설정
@MappedSuperclass
@Getter
-@Setter
public abstract class BaseEntity {
@CreationTimestamp
@Column(name = "created_at", updatable = false)
private LocalDateTime createdAt;
@UpdateTimestamp
@Column(name = "updated_at")
private LocalDateTime updatedAt;
@Column(name = "is_deleted")
private Boolean isDeleted = false;
+ public void markAsDeleted() {
+ this.isDeleted = true;
+ }
+
+ public void restore() {
+ this.isDeleted = false;
+ }
}📝 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.
| import lombok.Getter; | |
| import lombok.Setter; | |
| import org.hibernate.annotations.CreationTimestamp; | |
| import org.hibernate.annotations.UpdateTimestamp; | |
| import java.time.LocalDateTime; | |
| @MappedSuperclass | |
| @Getter | |
| @Setter | |
| import lombok.Getter; | |
| import lombok.Setter; | |
| import org.hibernate.annotations.CreationTimestamp; | |
| import org.hibernate.annotations.UpdateTimestamp; | |
| import java.time.LocalDateTime; | |
| @MappedSuperclass | |
| @Getter | |
| public abstract class BaseEntity { | |
| @CreationTimestamp | |
| @Column(name = "created_at", updatable = false) | |
| private LocalDateTime createdAt; | |
| @UpdateTimestamp | |
| @Column(name = "updated_at") | |
| private LocalDateTime updatedAt; | |
| @Column(name = "is_deleted") | |
| private Boolean isDeleted = false; | |
| public void markAsDeleted() { | |
| this.isDeleted = true; | |
| } | |
| public void restore() { | |
| this.isDeleted = false; | |
| } | |
| } |
backend/src/main/java/com/focussu/backend/config/SwaggerConfig.java
Outdated
Show resolved
Hide resolved
| username: admin | ||
| password: wlqwndgo1! |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
🛠️ Refactor suggestion
평문 비밀번호 노출 주의
개발 환경 설정에 DB 비밀번호(wlqwndgo1!)가 하드코딩되어 있습니다. application-secret.yml 또는 환경 변수로 민감 정보를 분리 관리하는 리팩토링이 필요합니다.
| kafka: | ||
| bootstrap-servers: ${KAFKA_BOOTSTRAP_SERVERS} | ||
| properties: | ||
| security.protocol: SSL | ||
|
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Kafka 설정 환경 변수 누락
bootstrap-servers: ${KAFKA_BOOTSTRAP_SERVERS} 설정이 있으나, CD 워크플로우에서 해당 변수를 전달하지 않습니다. 배포 시 Kafka 시크릿을 추가하거나 설정을 제거해주세요.
| spring: | ||
| config: | ||
| import: optional:application-secret.yml |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
🛠️ Refactor suggestion
시크릿 파일 import 경로 일관성
optional:application-secret.yml 대신 optional:classpath:application-secret.yml로 베이스 설정과 동일하게 classpath 경로를 명시하는 것이 안전합니다.
Resolved Issue #9
Summary by CodeRabbit
신규 기능
버그 수정
문서
스타일
기타