2주차 2부는 진짜... 길을 잃으며 나아가는 과정을 생중계한다고 보면 된다.
처음엔 단순했다. "CI/CD를 진행하려면 디렉토리 구조를 어떻게 해야 하지?"
고민했던 구조:
apps/backend/, apps/frontend/)모노레포가 도전적이고 배울 게 많긴 한데... 팀원한테 제대로 설명할 수 있을까? (나약함 이슈)
그리고 더 큰 문제는...
현실:
서버비를 줄이는 방법을 고민했다:
QA 서버를 로컬에서 테스트하자
QA 서버는 필요할 때만 켜자
근데 솔직히...
팀원이랑 대화하면서 "로컬 QA로 괜찮을까...?" 고민했는데, 실무 경험 없어서 확신이 안 섰다. 그래도 우리 서비스 복잡도 생각하면 로컬로도 충분할 것 같았음.
📝 팀원과의 대화 요약 (길어서 접음)타르트: 만약 로컬로 QA 할 경우 서버비 괜찮을 것 같아요?
나: EC2 4대 vs EC2 2대... 후자가 압도적으로 싸겠지?
타르트: 확실히 줄긴 하겠네. 근데 QA를 로컬로 돌려도 무리 없을까요?
나: 아니면 QA 서버는 필요할 때만 켜는 건 어떨까...?
타르트: 24시간 안 돌리고 필요할 때만 돌린다? 이게 더 맞는 방향 같긴 함.
나: 엉엉ㅇ어어렁놔ㅓㅠㅠ러ㅣ머ㅗㅇ라ㅓ뉴퓨ㅠㅠㅠㅠㅠㅠㅠㅠㅠㅠㅠㅠ (멘붕)
그래서 JVM 튜닝해서 GraalVM으로 돌리고, Docker 이미지 최소화해야겠네...
타르트: 들키지만 않으면 돈도 아끼고... 스크립트도 나중에 써도 되고...
나: 솔깃하네요 (솔깃)
3가지 옵션:
결국 B안(Docker Hub) 채택했다. ECR은 유료고, Docker Hub는 무료 플랜이 있어서.
###환경변수 관리
3가지 옵션:
B안(GitHub Secrets) 채택. AWS Secrets Manager는 유료고, GitHub Secrets면 충분함.
2가지 옵션:
솔직히 이건 내가 잘 몰라서... 일단 x86으로 시작하기로 했다.
3가지 옵션:
블루그린 해야지...
근데 솔직히 DAU 10명 서비스에 블루그린까지...? 오버엔지니어링 아닌가 싶긴 했음ㅋㅋ 그래서 이 내용은 추후 다시 고민하기로 했음
3가지 옵션:
제일 싼 게 EC2라는데... (후르츠츠츠) 일단 A안으로 시작하고 나중에 B안을 진행하기로 잡았다.
이 또한도 다음으로 미루는 것으로 했다.
팀원이랑 대화하다가 핵심 질문이 나왔다.
"자바로 마이그레이션하면 서버비만 더 나가는데, 왜 마이그레이션을 하는 거지?"
이게 진짜 치명타였다. 나도 순간 멘탈이 흔들렸음ㅋㅋㅋ
그래서 정리한 Python → Java 마이그레이션 이유:
근데 난 왜 아직도 부족하다고 느껴질까 고민고민중
드디어 실전. EC2 세팅부터 GitHub Actions까지 싹 다 했다.
인스턴스 정보:
cohi-chat-key.pem보안 그룹 설정:
| 타입 | 포트 | 소스 | 설명 |
|------|------|------|------|
| SSH | 22 | 0.0.0.0/0 | SSH 접속용 |
| HTTP | 80 | 0.0.0.0/0 | HTTP 웹 접속용 |
| Custom TCP | 8080 | 0.0.0.0/0 | Spring Boot |
문제 발생: 로컬에서 SSH 접속이 안 됨ㅠㅠ
ssh -i "cohi-chat-key.pem" ubuntu@3.34.99.110
# 결과: Connection timed out
시도한 것들:
icacls "cohi-chat-key.pem" /inheritance:r
icacls "cohi-chat-key.pem" /grant:r "$($env:USERNAME):(R)"원인: 로컬 네트워크/방화벽에서 SSH 포트 차단된 듯
해결: 집에서 진행...
브라우저에서 터미널이 뜸! 여기서 Docker 설치 진행.
# Docker 설치
curl -fsSL https://get.docker.com -o get-docker.sh
sudo sh get-docker.sh
sudo usermod -aG docker ubuntu
# Docker Compose 설치
sudo curl -L "https://github.com/docker/compose/releases/latest/download/docker-compose-$(uname -s)-$(uname -m)" -o /usr/local/bin/docker-compose
sudo chmod +x /usr/local/bin/docker-compose
# 설치 확인
docker --version
docker-compose --version
✅ 설치 완료!
GitHub Actions가 자동 배포하려면 민감한 정보들이 필요하다.
설정한 Secrets (총 5개):
1. DOCKER_USERNAME: Docker Hub 사용자명
2. DOCKER_TOKEN: Docker Hub Access Token
3. EC2_HOST: 3.34.99.110
4. EC2_USER: ubuntu
5. EC2_SSH_KEY: .pem 파일 전체 내용
EC2_SSH_KEY 값 준비 (PowerShell):
Get-Content C:\Users\hyeonyeong\Desktop\cohi-chat-key.pem | Out-String
이거 복사해서 GitHub Secrets에 붙여넣기.
QA 브랜치 Push 시:
QA 브랜치 Push
↓
[docker-build-push.yml 실행]
→ Gradle로 Spring Boot 빌드
→ Docker 이미지 생성
→ Docker Hub에 푸시
↓
[deploy.yml 실행]
→ EC2에 SSH 접속
→ Docker Hub에서 최신 이미지 Pull
→ docker-compose down (기존 컨테이너 중지)
→ docker-compose up -d (새 컨테이너 시작)
→ 헬스체크 확인
↓
배포 완료!
main 브랜치 Push 시:
로컬 SSH가 안 될 때 브라우저 기반 터미널로 대체 가능. 일시적인 네트워크 문제 우회 가능.
인바운드 규칙 제대로 안 설정하면 아무것도 작동 안 함. 필요한 포트: 22 (SSH), 80 (HTTP), 8080 (애플리케이션)
CI/CD에서 민감한 정보를 안전하게 관리. Docker Hub credentials, SSH keys 등을 코드에 노출하지 않음.
builder stage에서 빌드, runtime stage에서 실행. 최종 이미지 크기 최소화.
GitHub Actions → Docker Hub → EC2 흐름. 어디서든 같은 이미지를 pull 가능.
http://3.34.99.110:8080/actuator/health2주차는 진짜 정신없었다.
서버비 고민하면서 "왜 자바로 마이그레이션 했지?" 자기 회의도 들었고, EC2 SSH 접속 안 돼서 삽질도 했고... 그래도 결국 CI/CD 파이프라인까지 구축하는 데 성공했다.
현재 상태:
| 항목 | 상태 | 비고 |
|------|------|------|
| EC2 인스턴스 생성 | ✅ 완료 | IP: 3.34.99.110 |
| 보안 그룹 설정 | ✅ 완료 | 포트 22, 80, 8080 오픈 |
| Docker 설치 | ✅ 완료 | EC2 Instance Connect 사용 |
| GitHub Secrets | ✅ 완료 | 5개 모두 설정 |
| 로컬 SSH 접속 | ✅ 완료 | 네트워크 이슈 (우회 가능) |
| CI/CD 파이프라인 | ⏳ 대기 중 | 다음주 테스트 예정 |
준비 완료! 다음주에 워크플로우 실행만 하면 자동 배포가 시작된다. 🚀
길을 잃으며 나아가는 과정이 부끄럽긴 한데, 이게 진짜 개발 아닐까? ㅎㅎ
궁금한 거 있으면 댓글로 남겨주세요~ 👋