| 일 | 월 | 화 | 수 | 목 | 금 | 토 |
|---|---|---|---|---|---|---|
| 1 | 2 | 3 | 4 | |||
| 5 | 6 | 7 | 8 | 9 | 10 | 11 |
| 12 | 13 | 14 | 15 | 16 | 17 | 18 |
| 19 | 20 | 21 | 22 | 23 | 24 | 25 |
| 26 | 27 | 28 | 29 | 30 | 31 |
- 커뮤니티서버
- 문제선택근거
- JPA
- MVC
- springsecurity
- MVC요청플로우
- SEQUENCE
- JDBC
- 이벤트핸들러등록
- TDD
- 클린아키텍처
- Transaction
- string
- 공통규약
- 전전긍긍
- Ajax
- 이벤트핸들러this
- SpringLegacy
- 공통기술
- 단위테스트
- OOP
- 냄새라도
- 설정세팅
- 로그백
- model
- 디스크i/o
- index
- 사면초가
- AOP
- DDD
- Today
- Total
개발이군고구마
[멱살잡고 DevOps] 5. AWS EC2 설정 본문
[Backend Dockerfile]
1. backend Dockerfile 작성 🎆
[AWS Front 설정]
2. S3 버킷 & CloudFront 정적 웹 호스팅 활성화
[AWS EC2 설정] <- 현단계
3. EC2 인스턴스 프로비저닝
4. EC2 환경 구성 🎆
[CI/CD]
5. GitHub Actions CI/CD 구축 🎇
[테스트와 확장]
6.DNS 설정 및 최초 배포 테스트
7. 배포환경 분리 (dev/prod)
1. 인스턴스 시작하기
1) AmazonSSMManagedInstanceCore 정책 첨부
ㄴSSM Agent가 AWS Systems Manager와 안전하게 소통할 수 있도록 권한을 부여

2) 보안 그룹 설정
ㄴ타입 프로토콜 포트 범위 소스 설명
| SSH | TCP | 22 | 내 공인 IP (예: 203.0.113.25/32) | SSH 접속 허용 (비교적 안전) |
| HTTPS (CloudFront) | TCP | 443 | pl-xxxxxxxx (CloudFront Origin PRL) | CloudFront에서만 /api/* 요청 처리 |
✴CloudFront 엣지 위치 IP 범위를 나타내는 프리픽스 리스트
✴ SSH 대신 SSM Session Manager만 사용하려면 SSH 규칙을 제거해도 무방함
✅ CloudFront → Origin 통신 프로토콜
- Viewer→CloudFront: Viewer Protocol Policy 설정에 따라 HTTP 또는 HTTPS (보통 Redirect HTTP to HTTPS)
- CloudFront→Origin(EC2): Origin Protocol Policy에 따라
- 현재구성 : Viewer Protocol=Redirect HTTP to HTTPS, Origin Protocol=HTTPS Only 로 가정 시, 모든 요청은 포트 443(HTTPS) 으로 EC2의 Nginx에 전달

2. MongoDB EC2 IP추가와 Cloudfront behavior 경로 추가
1) MongoDB Atlas IP 화이트리스트에 EC2 IP 추가

2) CloudFront Behavior에 /api/* 경로 추가
ㄴ API 호출은 실시간 처리해야 하므로 캐싱을 비활성화하고, HTTPS만 허용하여 보안 유지


💥 Cloudfront 동작 설정 중 origin EC2 목록에 없음
- CloudFront 콘솔은 관리형 오리진만 나열해 주고, EC2 같은 “커스텀 오리진” 은 직접 입력
- Origin domain 직접 입력 또는 Elastic IP 사용
🌐 Cloudfront 원본 등록

💦 EC2 DNS 로 등록을 했으나, 서버가 죽고나서도 문제 없도록 탄력 ip를 연동해주는 것을 권장
3. Docker & Docker Compose EC2 설치
ㄴ EC2 에 Docker 와 Docker Compose가 있어야
⛳ 대안비교 - SSH 직접 로그인 뒤 명령 실행 → 보안 그룹 SSH 허용·키 관리 부담 증가
✅ SSM Run Command → SSH 없이 AWS 콘솔 GUI에서 바로 원격 명령 실행, AWS IAM 권한만으로 안전
AWS System Manager 에서
EC2를 타켓으로 한 후 AWS-RunShellScript 로 스크립트 명령어를 작성하여 설치
Amazon Linux 2023
sudo dnf update -y
sudo dnf install -y docker
sudo systemctl start docker
sudo systemctl enable docker
# 현재 사용자를 'docker' 그룹에 추가
# 이렇게 하면 매번 sudo를 붙이지 않아도 docker 명령을 쓸 수 있음
sudo usermod -aG docker ec2-user
# 6. 변경된 그룹 권한을 적용하기 위해 세션을 종료하고 다시 연결
# 브라우저 탭을 닫고, 7-1 단계에 따라 다시 SSM으로 접속
exit
# 7. 최신 버전의 Docker Compose를 GitHub에서 직접 다운로드
sudo curl -L "https://github.com/docker/compose/releases/latest/download/docker-compose-$(uname -s)-$(uname -m)" -o /usr/local/bin/docker-compose
# 8. 다운로드한 파일에 실행 권한을 부여
sudo chmod +x /usr/local/bin/docker-compose
docker --version
docker-compose --version

4. Docker Compose 및 Nginx 파일 수정
ㄴ Docker compose는 현재 프리티어 환경에서 실무 패턴가 가깝기 때문에 채택
ㄴ github -> EC2 배포
⛳ 대안비교 - AWS ECS/EKS
여러 개의 EC2 에 각기 다른 컨테이너를 pull할 수 있으나 현재 사이즈에선 불필요하다 판단하여 사용하지 않는다.
1) Docker Compose 파일 작성 및 배치 (기존에 썼던 파일을 수정)
- backend 서비스의 ports 설정 제거
- Node.js 백엔드 컨테이너의 5000번 포트를 EC2 서버의 5000번 포트에 직접 노출 -> 보안적으로 매우 위험
- 모든 API 요청은 반드시 Nginx 리버스 프록시를 통해서만 백엔드로 전달되어야 함
- backend와 nginx는 app-net이라는 내부 네트워크로 이미 연결되어 있으므로, Nginx는 외부 노출 없이도 backend:5000으로 접근할 수 있음
- backend 서비스에 image 속성 추가
- GitHub Actions가 코드를 빌드하여 {도커헙아이디}/{이미지 이름}:latest 라는 이미지(Image)를 만들어 Docker Hub에 올리면, EC2 서버에서는 build를 다시 하는 것이 아니라 완성된 이미지를 pull 받아서 사용
- 역할(빌드는 CI서버, 실행은 EC2서버)을 명확히 분리하는 것이 효율적이고 일관된 배포를 보장
- logging 드라이버 설정 추가
- 컨테이너의 로그를 EC2 인스턴스가 아닌 CloudWatch에 중앙 집중적으로 기록 -> 여러 서버, 여러 컨테이너의 로그를 한 곳에서 보고 검색
- EC2 생성시 만들었던 IAM 역할에 정책을 추가해주어야 함

2) Nginx 구성 파일 마운트
- server_tokens off; 추가
- Nginx는 에러 페이지나 HTTP 응답 헤더에 nginx/1.25.5 와 같은 버전 정보를 노출
- 지시어는 버전 정보를 숨겨서 불필요한 정보 노출을 막는 간단하지만 효과적인 보안 설정
- client_max_body_size 10M; 추가
- 악의적인 사용자가 매우 큰 용량의 요청(예: 대용량 파일 업로드)을 보내 서버의 리소스를 고갈시키는 서비스 거부(DoS) 공격을 방지
3) .env 파일에 gitignore에 업로드
ㄴ 수동으로 .env 파일을 생성하고 내용을 입력
echo ".env" >> .gitignore
5. 배포 파일 준비 및 애플리케이션 실행
ㄴ "Build, release, run" 이라는 12-Factor App 방법론의 핵심 원칙
ㄴ 코드를 빌드하고(Build), 실행 가능한 산출물(Docker 이미지)로 묶고(Release), 실제 환경에서 실행(Run)하는 단계 명확히 분리

# ec2-user 계정으로 전환
sudo su - ec2-user
# ec2-user의 홈 디렉토리로 이동
cd /home/ec2-user
git clone https://github.com/<YOUR_GITHUB_USERNAME>/<YOUR_BACKEND_REPO>.git
# 생성된 프로젝트 디렉토리로 이동
cd <YOUR_BACKEND_REPO>
# env 파일 생성 후 직접 입력 (mongoDB 정보)
# docker-compose.yml 파일에 정의된 모든 컨테이너를 백그라운드에서 실행
# -d 옵션은 'detached mode'를 의미하며, 터미널 세션이 끊겨도 컨테이너가 계속 실행
docker-compose up -d
# 확인
docker-compose ps
docker-compose logs -f node-app


💥 unknown log opt 'awslogs-stream-prefix' for awslogs log driver
docker compose 에 작성한 awslogs-stream-prefix 옵션은 비교적 최신 Docker 버전에 추가된 편의 기능
EC2의 Docker 버전이 이 옵션을 지원하지 않아 오류가 발생
🌐 현재 설치된 Docker 버전과 호환되는 옵션으로 docker-compose.yml 파일을 수정
# [수정] 'awslogs-stream-prefix'를 'awslogs-stream'으로 변경하고, 스트림 이름을 직접 지정
awslogs-stream: "node-app-stream"
awslogs-create-group: "true"

'Cloud Deploy' 카테고리의 다른 글
| [멱살잡고 DevOps] 7. DNS 설정 및 테스트 (트러블 슈팅🎯) (0) | 2025.07.26 |
|---|---|
| [멱살잡고 DevOps] 6. GitHub Actions CI/CD 구축 (1) | 2025.07.23 |
| [멱살잡고 DevOps] 4. AWS S3/Cloudfront 설정 (1) | 2025.07.18 |
| [멱살잡고 DevOps] 3. Backend Dockerfile (docker compose/docker hub) (0) | 2025.07.17 |
| [멱살잡고 DevOps] 2. 배포 아키텍처 설계 (0) | 2025.07.15 |