[이종호] Sprint 8#176
Hidden character warning
Conversation
- 변경한 내용: * 기본요구사항 3가지에 대한 상세 코드리뷰 문서 작성 * 초보자 대상 코드 설명 (일처리 순서, 줄별 해설) * 요구사항 체크리스트 100% 대조 검증 결과 포함 - 변경 이유: * 구현 코드에 대한 이해도 향상 및 학습 자료 제공 * 기본요구사항과 코드의 일치 여부 문서화 - 주요 파일: * docs/sprint8-기본요구사항-코드리뷰.md
- 변경한 내용: * 런타임 스테이지를 amazoncorretto:17-alpine으로 변경 (경량 이미지) * 의존성 파일 먼저 복사 후 빌드하여 레이어 캐시 최적화 * 태그: local-slim (878MB → 594MB, 약 32% 감소) - 변경 이유: * 스프린트 8 심화요구사항 - 이미지 최적화 - 주요 파일: * Dockerfile
- 변경한 내용: * .github/workflows/test.yml 생성 * main 브랜치 PR 시 자동 테스트 실행 * JDK 17 (Corretto) + Gradle 캐시 설정 * JaCoCo 커버리지 리포트를 CodeCov에 업로드 - 변경 이유: * 스프린트 8 심화요구사항 - CI 파이프라인 구축 - 주요 파일: * .github/workflows/test.yml
- 변경한 내용: * 루트 README.md 생성 * CodeCov 커버리지 뱃지 추가 * 프로젝트 빌드/실행 가이드 포함 - 변경 이유: * 스프린트 8 심화요구사항 - CodeCov 뱃지 추가 - 주요 파일: * README.md
- 변경한 내용: * .github/workflows/deploy.yml 생성 * release 브랜치 푸시 시 자동 배포 실행 * build-and-push Job: Public ECR 로그인, Docker 빌드/푸시 (latest + 커밋해시 태그) * deploy Job: 태스크 정의 업데이트, 기존 서비스 중단, 새 태스크로 서비스 업데이트 - 변경 이유: * 스프린트 8 심화요구사항 - CD 파이프라인 구축 - 주요 파일: * .github/workflows/deploy.yml
- 변경한 내용: * docs/sprint8-심화요구사항.md - 심화요구사항 전체 정리 * docs/sprint8-심화-설계서.md - 설계 및 구현 계획 - 변경 이유: * 스프린트 8 심화요구사항 문서화 - 주요 파일: * docs/sprint8-심화요구사항.md * docs/sprint8-심화-설계서.md
This reverts commit d85caed.
- 변경한 내용: * @activeprofiles("test") 추가하여 H2 인메모리 DB 사용 - 변경 이유: * CI 환경(GitHub Actions)에서 PostgreSQL 미설치로 contextLoads 실패 - 주요 파일: * src/test/java/.../DiscodeitApplicationTests.java
- 변경한 내용: * badge URL에서 /branch/main 경로 제거 - 변경 이유: * main 브랜치에 커버리지 미업로드 상태에서 unknown 표시되는 문제 해결 - 주요 파일: * README.md
- 변경한 내용: * codecov.yml 생성, 기본 브랜치를 이종호8-로 설정 - 변경 이유: * main 브랜치에 커버리지 미업로드 상태에서 뱃지가 unknown 표시되는 문제 해결 - 주요 파일: * codecov.yml
- 변경한 내용: * AWS 콘솔 스크린샷 6장 추가 (RDS, ECR, ECS, VPC, IAM) * .env.example에 AWS RDS 접속 정보 추가 (키 제외) - 변경 이유: * PR 리뷰를 위한 인프라 구성 증빙 자료 - 주요 파일: * screenshots/*.png * .env.example
- 변경한 내용: * IntelliJ SSH/SSL 탭 설정 스크린샷 추가 * SSH 구성 상세 (호스트, 키 페어 인증) 스크린샷 추가 * SSH 터널링 연결 테스트 성공 스크린샷 추가 - 변경 이유: * 기본요구사항 - SSH 터널링을 통한 RDS 접근 증빙 - 주요 파일: * screenshots/ssh-tunnel-tab.png * screenshots/ssh-tunnel-config.png * screenshots/ssh-tunnel-test-success.png
- 변경한 내용: * 전체 화면 스크린샷에서 브라우저 콘텐츠 영역만 크롭 * macOS 메뉴바, 브라우저 탭바, AWS 네비게이션 바, 하단 빈 공간 제거 * IAM 사용자 스크린샷을 권한 정책 페이지로 교체 - 변경 이유: * PR 첨부용 스크린샷의 가독성 향상 - 주요 파일: * screenshots/rds-instance.png * screenshots/vpc-sg-rds.png * screenshots/vpc-sg-ecs.png * screenshots/ecr-images.png * screenshots/ecs-task.png * screenshots/iam-user.png
- 변경한 내용: * HELP.md (Spring Initializr 기본 파일) 삭제 * AI 분석 비교 문서 5개 삭제 (code-analysis-*, sonnet-vs-opus, pagination-comparison) * Dockerfile에 멀티 스테이지 빌드, 레이어 캐시 설명 주석 추가 * docker-compose.yml에 서비스별 역할, 환경변수 설명 주석 추가 - 변경 이유: * PR에 불필요한 파일 제거로 코드 정리 * 초보자가 Docker 설정을 이해할 수 있도록 주석 보강 - 주요 파일: * Dockerfile * docker-compose.yml
- 변경한 내용: * 기존 스크린샷 9장 삭제, 새 스크린샷 7장으로 교체 * RDS 인스턴스 상세 + SSH 터널링 테이블 목록 포함 * ECS 태스크 상세 구성정보 (Public IP 포함) * VPC 보안그룹 인바운드 규칙 (ECS용, RDS SSH용) * IAM 사용자 권한 정책 - 변경 이유: * 스프린트8 PR 리뷰 요구사항에 맞게 스크린샷 재촬영 * DataGrip 테이블 목록 누락 보완 - 주요 파일: * screenshots/1-1.RDS-Instances-Details.png * screenshots/1-2.RDS-SSH-tunneling.png * screenshots/2.ECR-Image.png * screenshots/3.ECS-Tasks-Details.png * screenshots/4.VPC-Security-Inbound1.png * screenshots/4.VPC-Security-Inbound2.png * screenshots/5.IAM-User.png
- 변경한 내용: * .env.example 파일 삭제 - 변경 이유: * 요구사항에 없는 파일이므로 제거 * .env 파일은 .gitignore로 형상관리 제외, PR 본문에 별도 첨부 - 주요 파일: * .env.example (삭제)
코드 리뷰 반영 - Docker 빌드 오류 수정 및 환경 설정 정리커밋: 변경한 내용
변경 이유
주요 파일
|
- 변경한 내용: * Dockerfile 1행 잘못 포함된 텍스트 제거 * 빌드 태스크를 build에서 bootJar로 변경 (실행 JAR만 생성) * ENTRYPOINT에 -Dserver.port=80 명시로 포트 설정 명확화 * .continue/mcpServers/ 불필요한 IDE 설정 파일 삭제 * .gitignore에 .continue/ 추가 (재발 방지) * .env.example 복원 (민감 정보 제거한 템플릿) - 변경 이유: * Dockerfile 1행에 잘못 포함된 텍스트로 Docker 빌드 실패 가능성 존재 * bootJar 태스크가 build보다 효율적 (실행 가능 JAR만 생성) * -Dserver.port=80 명시로 ECS 배포 시 포트 설정 안정성 확보 * IDE 설정 파일이 PR에 포함되어 불필요한 노이즈 발생 * .env.example이 없으면 새 개발자가 필요 환경변수를 파악 불가 - 주요 파일: * Dockerfile * .env.example * .gitignore * .continue/mcpServers/ (삭제)
- 변경한 내용:
* S3 테스트: .env 파일 없을 때 환경변수에서 자격증명 로드 (loadConfig 메서드)
* test.yml: S3 자격증명을 GitHub Secrets로 주입 (CI에서 S3 테스트 실행 가능)
* deploy.yml: 수동 jq 조작을 공식 ECS 액션으로 대체
- aws-actions/amazon-ecs-render-task-definition@v1 (태스크 정의 렌더링)
- aws-actions/amazon-ecs-deploy-task-definition@v1 (배포)
* deploy.yml: 서비스 중단 후 services-stable 대기 추가 (프리티어 안정성)
- 변경 이유:
* 기존 S3 테스트는 .env 파일에만 의존하여 CI 환경에서 실행 불가능
* 환경변수 fallback으로 로컬(.env)과 CI(Secrets) 양쪽 지원
* 공식 AWS 액션은 유지보수성이 높고 태스크 정의 필드 삭제 등 엣지 케이스 처리
* 서비스 scale-down 후 stable 대기로 EC2 프리티어 슬롯 충돌 방지
- 주요 파일:
* .github/workflows/test.yml
* .github/workflows/deploy.yml
* src/test/java/com/sprint/mission/discodeit/storage/s3/AWSS3Test.java
* src/test/java/com/sprint/mission/discodeit/storage/s3/S3BinaryContentStorageTest.java
CI/CD 파이프라인 안정성 개선커밋: 다른 PR 리뷰에서 확인된 개선점을 반영했습니다. 1. CI에서 S3 테스트 실행 가능하도록 개선문제: 기존 S3 테스트( 개선: private Properties loadConfig() throws IOException {
Properties props = new Properties();
if (Files.exists(Paths.get(".env"))) {
try (FileInputStream fis = new FileInputStream(".env")) {
props.load(fis);
}
} else {
// CI 환경: 환경변수에서 로드
for (String key : new String[]{"AWS_S3_ACCESS_KEY", "AWS_S3_SECRET_KEY", ...}) {
String value = System.getenv(key);
if (value != null) props.setProperty(key, value);
}
}
return props;
}
env:
AWS_S3_ACCESS_KEY: ${{ secrets.AWS_ACCESS_KEY }}
AWS_S3_SECRET_KEY: ${{ secrets.AWS_SECRET_KEY }}
AWS_S3_REGION: ${{ vars.AWS_REGION }}
AWS_S3_BUCKET: ${{ secrets.AWS_S3_BUCKET }}
2. 공식 AWS ECS 액션 사용으로
|
| - name: AWS CLI 설정 (Public ECR용 - us-east-1) | ||
| uses: aws-actions/configure-aws-credentials@v4 | ||
| with: | ||
| aws-access-key-id: ${{ secrets.AWS_ACCESS_KEY }} |
There was a problem hiding this comment.
현업에서는 보안적인 관점에서 ACCESS_KEY보다는 Role 방식으로 인증하오니 참고 부탁드립니다.
There was a problem hiding this comment.
피드백 감사합니다.
현재 스프린트8 기본요구사항에서 IAM 사용자 생성, 엑세스 키 생성 -> .env 파일에 추가 흐름이 명시되어 있어서 요구사항에 따른 내용입니다.
말씀해주신 Role 방식은 좀 더 공부하고 확인해서 다른 프로젝트에서 사용 할 수 있도록 준비하겠습니다.
| run: | | ||
| aws ecr-public get-login-password --region us-east-1 | docker login --username AWS --password-stdin public.ecr.aws | ||
|
|
||
| - name: Docker 이미지 빌드 및 푸시 |
There was a problem hiding this comment.
미션 8 요구사항에서는 docker-compose와 Dockerfile을 활용해야하기 때문에 CI/CD 과정에서 도커 이미지를 생성하신 것 같아요.
해당 방법 외에 JIB 플러그인을 활용해서 CI/CD 과정에서 도커 설치없이 이미지를 생성할 수 있으니 참고부탁드려요.
There was a problem hiding this comment.
JIB는 처음 들어봐서 찾아봤는데 Docker 데몬 없이 이미지를 빌드/푸시할 수 있다는 점이 확실히 장점이네요.
이번 스프린트미션 8 기본요구사항이 Dockerfile 작성 + docker-compose 구성을 명시하고 있어서 해당 방식으로 구현했습니다.
JIB 공부를 해서 빌드 파이프라인에서 Docker 설치 자체를 덜어낼 수 있는 방법을 현업에서 사용해 볼 수 있도록 노력하겠습니다.
| - name: 테스트 실행 | ||
| run: ./gradlew clean test | ||
| env: | ||
| # S3 테스트용 자격증명 (GitHub Secrets). 값이 비어있으면 S3 테스트는 자동 스킵됨. |
| build: . # 로컬 Dockerfile로 이미지 빌드 | ||
| ports: | ||
| - "${APP_PORT:-8080}:80" | ||
| - "${APP_PORT:-8080}:80" # 호스트:컨테이너 포트 매핑 |
There was a problem hiding this comment.
Dockerfile 에 정의된 Entrypoint에서도 80 Port 띄우던데 혹시 애플리케이션을 실행하는 Port를 80으로 선정하신 이유는 요구사항 때문이군요.
80 Port는 잘 알려진 즉 HTTP 프로토콜이 사용하는 Port라 사용하지 않고 Java Application을 구동할 때 보통 8080 Port를 사용하며 호스트와 컨테이너 간 포트 포워딩을 통해 진행합니다.
There was a problem hiding this comment.
공감합니다.
저도 처음엔 8080으로 하고 싶었는데,
이번 미션 기본요구사항의 Dockerfile 체크리스트에 "80 포트 노출"이 명시되어있고 ECS 태스크 정의에서도 "호스트 80, 컨테이너 80"을 요구하고 있어서 컨테이너 포트를 80으로 맞췄습니다.
다만 로컬 개발 환경의 docker-compose에서는 말씀해주신 관례대로 ${APP_PORT:-8080}:80으로 호스트 측은 8080으로 포워딩해두었습니다.
이 부분을 리뷰 코멘트에 같이 기재했어야 했는데 설명이 부족했던 것 같습니다.
| @@ -35,6 +35,9 @@ bin/ | |||
| ### VS Code ### | |||
| .vscode/ | |||
|
|
|||
There was a problem hiding this comment.
제가 못찾는건지 모르겠지만 gitignore 파일에 .env 파일 정의가 없네요.
|
IAM에 Role을 부여할 때 최소 권한의 원칙(Principle of Least Privilege, PoLP)를 기준으로 부여한다고 생각해주시면 좋을 것 같습니다.! |
|
PR 변경점에는
이 파일들이 존재하지 않네요ㅠㅠ |
|
S3 Bucket 이미지도 있으면 좋을 것 같습니다! |
|
RDS를 Private Subnet 위치에 존재하게 하기 때문에 Bastion Server(rds-ssh)를 통해 SSH 터널링을 활용하여 로컬에서 접근하니 참고 부탁드려요. |
최소 권한의 원칙, 말씀해주셔서 감사합니다. 실제 S3 연동에서 사용하는 API는 PutObject, GetObject, DeleteObject, ListBucket 정도로 한정되므로, 다음부터는 개인적으로 정책 파일을 만들어서 적용해보겠습니다. |
확인해주셔서 감사합니다. 말씀하신 항목들은 모두 구현되어 있는데,
확인이 어려우셨던 점 반영해서 다음 PR에서는 base 브랜치 포함 변경 범위를 본문에 별도로 정리해 올리겠습니다. |
다행이네요 RDS는 퍼블릭 액세스를 "아니오"로 두고 프라이빗 서브넷에 위치 시켰고, 접근이 필요할 땐 초기화 스크립트 실행 후에는 과금을 피하려고 해당 EC2를 삭제했습니다. |
|
피드백 해주신 내용 감사합니다. 답변 드린 것 처럼 코드를 따로 수정할 내용이 없는 것 같아서 |


스프린트 8
기본요구사항
1. 애플리케이션 컨테이너화
Dockerfile 작성
/app).dockerignore로 제외)PROJECT_NAME: discodeit,PROJECT_VERSION: 1.2-M8)JVM_OPTS: 기본값 빈 문자열)이미지 빌드 및 실행 테스트
local) 지정prod프로필로 실행http://localhost:8081로 접속 가능하도록 포트 매핑Docker Compose 구성
.env파일 활용, 형상관리 제외)schema.sql자동 실행되도록 구성depends_on)--build플래그 사용)2. BinaryContentStorage 고도화 (AWS S3)
AWS S3 버킷 구성
discodeit-binary-content-storage-(이니셜)형식)AWS S3 접근을 위한 IAM 구성
discodeit) 생성AmazonS3FullAccess권한 할당.env파일에 추가AWS S3 테스트
software.amazon.awssdk:s3:2.31.7)AWSS3Test).env에 정의한 AWS 정보 로드S3BinaryContentStorage 구현
클래스 다이어그램:
discodeit.storage.type값이s3인 경우에만 Bean 등록S3BinaryContentStorageTest를 함께 작성하면서 구현application.yaml수정 (BinaryContentStorage 설정 유연화).env파일에서 임포트download메소드는 PresignedUrl을 활용해 리다이렉트 방식으로 구현3. AWS를 활용한 배포 (AWS RDS, ECR, ECS)
AWS RDS 구성
discodeit-db, 프리티어)SSH 터널링을 통한 RDS 접근 (EC2)
rds-ssh)AWS ECR 구성
discodeit) 생성aws configure실행AmazonElasticContainerRegistryPublicFullAccess권한 부여latest,1.2-M8)AWS ECS 구성
discodeit.env) 작성 및 S3 업로드discodeit-cluster, EC2 t2.micro)discodeit-task, EC2, bridge, CPU 0.25 vCPU, 메모리 0.5 GB)discodeit-service, 원하는 태스크 1, 상태 검사 유예 기간 30초)배포 접속 확인:
심화요구사항
1. 이미지 최적화하기
local-slim)2. GitHub Actions를 활용한 CI/CD 파이프라인 구축
CI (지속적 통합) 워크플로우
.github/workflows/test.yml파일 생성main브랜치에 PR이 생성되면 실행되도록 설정CD (지속적 배포) 워크플로우
.github/workflows/deploy.yml파일 생성release브랜치에 코드가 푸시되면 실행되도록 설정AWS 정보 설정
AWS_ACCESS_KEY,AWS_SECRET_KEY)AWS_REGION,ECR_REPOSITORY_URI,ECS_CLUSTER,ECS_SERVICE,ECS_TASK_DEFINITION)Docker 이미지 빌드 및 푸시
us-east-1)latest+ GitHub 커밋 해시ECS 서비스 업데이트
AWS_REGION)aws ecs update-service --desired-count 0)기능별 커밋 내역
a5118aeb03a1ea536fed20dc699b071b0b6792ab440aacc94491a464ec809932e7ba78adf8ef3b9170726450451ae870CI/CD 파이프라인 개선 및 검증 (2026-04-10)
개선 내용
clean bootJar -x test로 변경해 테스트 빌드 제외-Dserver.port=80추가해 prod 프로파일과 일관성 확보.env.example: 민감값을 플레이스홀더로 치환해 로컬 개발 가이드 복원AWSS3Test,S3BinaryContentStorageTest)loadConfig()헬퍼 추가:.env존재 시 파일, 없으면 환경변수에서 로드assumeTrue로 자격증명 미설정 시 자동 스킵 → 로컬/CI 양쪽 대응.github/workflows/test.yml: S3 시크릿 주입 (AWS_S3_ACCESS_KEY,AWS_S3_SECRET_KEY,AWS_S3_REGION,AWS_S3_BUCKET).github/workflows/deploy.ymlaws-actions/amazon-ecs-render-task-definition@v1,aws-actions/amazon-ecs-deploy-task-definition@v1.gitignore:.continue/추가검증 결과
latest,${{ github.sha }})discodeit-service) 새 태스크 정의 revision 배포 성공리뷰를 위한 첨부 자료
.env 파일 (엑세스 키, 시크릿 키 제외)
RDS
ECR
ECS
VPC
IAM