AWS Spring/React/Next.js/React Native 배포 가이드 (A to Z)
이 문서는 다양한 유형의 애플리케이션을 AWS(Amazon Web Services)에 배포하는 전체적인 과정을 안내합니다. 각 프로젝트의 특성에 맞는 최적의 배포 전략을 A부터 Z까지 상세히 다룹니다.
목차
사전 준비 사항
- AWS 계정 생성
- AWS CLI 설치 및 구성
- 각 프로젝트별 빌드 도구 준비 (JDK, Node.js, etc.)
Part 1: Spring Boot 프로젝트 배포
- Option A: AWS Elastic Beanstalk (가장 쉬운 방법)
- RDS (데이터베이스) 연동 포함
- Option B: Amazon EC2 + Docker (유연한 방법)
- ECR (컨테이너 레지스트리) 사용
- Nginx (리버스 프록시) 설정
- Option A: AWS Elastic Beanstalk (가장 쉬운 방법)
Part 2: React (Client-Side Rendering) 프로젝트 배포
- Option A: S3 + CloudFront (표준적이고 저렴한 방법)
- React Router 문제 해결 포함
- Option B: AWS Amplify (가장 간편한 CI/CD 통합)
- Option A: S3 + CloudFront (표준적이고 저렴한 방법)
Part 3: Next.js (Server-Side Rendering) 프로젝트 배포
- Option A: AWS Amplify (SSR/ISR 완벽 지원)
- Option B: Amazon ECS (Fargate) + Docker (고급 확장형)
Part t 4: React Native 앱 배포 (백엔드 및 빌드 자동화)
- 모바일 앱 배포의 개념
- 백엔드 API 서버 배포 (Part 1 참고)
- CI/CD: AWS CodePipeline + CodeBuild를 이용한 앱 빌드 자동화
Part 5: 공통 서비스 및 모범 사례
- IAM: 보안을 위한 사용자/역할 관리
- Route 53: 도메인 연결
- ACM: 무료 SSL 인증서 발급
- Cost Management: 비용 관리 및 알림 설정
1. 사전 준비 사항
AWS 계정 생성
- AWS 공식 홈페이지에서 회원가입을 진행합니다.
- 결제 정보 등록이 필요하며, 가입 후 1년간 제공되는 프리티어를 활용할 수 있습니다.
AWS CLI 설치 및 구성
- AWS 서비스를 커맨드 라인에서 제어하기 위한 필수 도구입니다.
- 설치:
# Windows (PowerShell) msiexec.exe /i https://awscli.amazonaws.com/AWSCLIV2.msi # macOS curl "https://awscli.amazonaws.com/AWSCLIV2.pkg" -o "AWSCLIV2.pkg" sudo installer -pkg AWSCLIV2.pkg -target / - 구성:
- AWS 콘솔에서 IAM 사용자를 생성하고,
Access Key와Secret Access Key를 발급받습니다. (보안상 Root 계정 키 사용은 절대 금물) - 터미널에서 아래 명령어를 실행하고 발급받은 키와 정보를 입력합니다.
aws configure AWS Access Key ID [None]: YOUR_ACCESS_KEY AWS Secret Access Key [None]: YOUR_SECRET_KEY Default region name [None]: ap-northeast-2 # (서울 리전) Default output format [None]: json
- AWS 콘솔에서 IAM 사용자를 생성하고,
Part 1: Spring Boot 프로젝트 배포
Option A: AWS Elastic Beanstalk (EB)
PaaS(Platform as a Service)로, 인프라 관리에 대한 부담 없이 코드만 업로드하면 자동으로 환경을 구성해줍니다.
1. 프로젝트 빌드
.jar또는.war파일을 생성합니다. Gradle 기준:./gradlew buildbuild/libs/폴더에 생성된.jar파일을 확인합니다.
2. Elastic Beanstalk 환경 생성
- AWS 콘솔에서 'Elastic Beanstalk' > '새 애플리케이션 생성' > '새 환경 생성'.
- 플랫폼 선택:
Java선택, 버전은 프로젝트와 맞는 버전을 선택합니다. - 소스 코드 업로드: 위에서 빌드한
.jar파일을 업로드합니다. - 잠시 기다리면 서버 URL이 생성되며 배포가 완료됩니다.
3. RDS (데이터베이스) 연동
- RDS 인스턴스 생성: AWS 콘솔에서 'RDS' > '데이터베이스 생성' > 원하는 DB 엔진(MySQL, PostgreSQL 등) 선택.
- EB와 연동:
- EB 환경의 '구성' > '데이터베이스' > '수정'으로 이동합니다.
- 여기서 RDS를 생성하거나 기존 RDS에 연결할 수 있습니다.
- EB가 RDS에 접근할 수 있도록 보안 그룹이 자동으로 구성됩니다.
- 환경 변수 설정: DB 접속 정보(Host, Username, Password)는
application.yml에 직접 하드코딩하지 않고, EB 환경의 '구성' > '소프트웨어' > '환경 속성'에 등록하여 사용합니다.spring: datasource: url: ${DB_URL} username: ${DB_USERNAME} password: ${DB_PASSWORD}
Option B: Amazon EC2 + Docker
IaaS(Infrastructure as a Service)로, 가상 서버(EC2)를 직접 생성하고 모든 환경을 수동으로 구성하여 유연성이 높습니다.
1. Dockerfile 작성
프로젝트 최상단에
Dockerfile을 작성합니다.# 베이스 이미지 FROM openjdk:17-jdk-slim # JAR 파일 경로 변수 ARG JAR_FILE=build/libs/*.jar # JAR 파일을 컨테이너로 복사 COPY ${JAR_FILE} app.jar # 실행 포트 EXPOSE 8080 # 애플리케이션 실행 ENTRYPOINT ["java","-jar","/app.jar"]
2. ECR(Elastic Container Registry)에 이미지 푸시
ECR은 Private Docker Image 저장소입니다.
AWS 콘솔에서 'ECR' > '리포지토리 생성'.
리포지토리 생성 후 '푸시 명령 보기'를 클릭하면 아래와 유사한 가이드가 나옵니다.
# 1. AWS CLI를 통해 ECR에 로그인 aws ecr get-login-password --region ap-northeast-2 | docker login --username AWS --password-stdin YOUR_AWS_ACCOUNT_ID.dkr.ecr.ap-northeast-2.amazonaws.com # 2. Docker 이미지 빌드 docker build -t my-spring-app . # 3. ECR 리포지토리 URI로 이미지 태그 지정 docker tag my-spring-app:latest YOUR_AWS_ACCOUNT_ID.dkr.ecr.ap-northeast-2.amazonaws.com/my-spring-app:latest # 4. ECR로 이미지 푸시 docker push YOUR_AWS_ACCOUNT_ID.dkr.ecr.ap-northeast-2.amazonaws.com/my-spring-app:latest
3. EC2 인스턴스 설정 및 배포
AWS 콘솔에서 'EC2' > '인스턴스 시작'.
AMI 선택:
Amazon Linux 2또는Ubuntu추천.인스턴스 유형: 프리티어 사용 가능
t2.micro.보안 그룹:
80(HTTP),443(HTTPS),22(SSH)포트를 열어줍니다.EC2 접속 후 Docker 설치:
sudo yum update -y sudo amazon-linux-extras install docker -y sudo service docker start sudo usermod -a -G docker ec2-user # 재로그인 필요ECR 로그인 및 컨테이너 실행:
# ECR 로그인 (위와 동일) aws ecr get-login-password --region ap-northeast-2 | docker login ... # Docker 이미지 pull docker pull YOUR_AWS_ACCOUNT_ID.dkr.ecr.ap-northeast-2.amazonaws.com/my-spring-app:latest # Docker 컨테이너 실행 (환경 변수 -e 옵션으로 전달) docker run -d -p 8080:8080 \ -e DB_URL=... \ -e DB_USERNAME=... \ --name my-app \ YOUR_AWS_ACCOUNT_ID.dkr.ecr.ap-northeast-2.amazonaws.com/my-spring-app:latest(선택) Nginx 설정: 80번 포트로 들어온 요청을 8080 포트로 전달(리버스 프록시)하거나, 도메인 연결 및 SSL 적용을 위해 Nginx를 설치하고 설정합니다.
Part 2: React (CSR) 프로젝트 배포
Option A: S3 + CloudFront
정적 파일(HTML, CSS, JS)을 S3에 저장하고, CloudFront라는 CDN을 통해 전 세계 사용자에게 빠르고 안전하게 제공합니다.
1. 프로젝트 빌드
build폴더에 정적 파일들이 생성됩니다.npm run build
2. S3 버킷 생성 및 설정
- AWS 콘솔에서 'S3' > '버킷 만들기'.
- (중요) '모든 퍼블릭 액세스 차단'을 해제합니다.
- '속성' 탭 > '정적 웹 사이트 호스팅' > '활성화'. 인덱스 문서를
index.html로 지정. - '권한' 탭 > '버킷 정책'에 아래 정책을 추가하여 퍼블릭 읽기를 허용합니다.
{ "Version": "2012-10-17", "Statement": [ { "Sid": "PublicReadGetObject", "Effect": "Allow", "Principal": "*", "Action": "s3:GetObject", "Resource": "arn:aws:s3:::YOUR_BUCKET_NAME/*" } ] } - 생성된
build폴더 안의 모든 파일을 S3 버킷에 업로드합니다.
3. CloudFront 배포 생성
- AWS 콘솔에서 'CloudFront' > '배포 생성'.
- 원본 도메인: 위에서 생성한 S3 버킷의 웹 사이트 엔드포인트를 선택합니다.
- (중요) React Router 오류 해결: '오류 페이지' 탭 > '사용자 정의 오류 응답 생성' 클릭.
- HTTP 오류 코드:
404 Not Found - 오류 응답 사용자 정의:
예 - 응답 페이지 경로:
/index.html - HTTP 응답 코드:
200 - 이렇게 설정하면 어떤 경로로 접속해도
index.html을 먼저 로드하여 React Router가 경로를 처리하게 됩니다.
- HTTP 오류 코드:
- 배포가 완료되면 생성된 CloudFront 도메인으로 접속할 수 있습니다.
Option B: AWS Amplify
Git Repository를 연결하기만 하면 빌드부터 배포, CI/CD까지 자동으로 처리해주는 가장 간편한 서비스입니다.
- AWS 콘솔에서 'Amplify' > '새 앱 호스팅'.
GitHub,BitBucket,GitLab등 Git 제공업체 선택 및 리포지토리 연결.- 브랜치 선택 후 Amplify가 자동으로 빌드 설정을 감지합니다. (
amplify.yml파일이 생성됨) - '저장 및 배포'를 클릭하면 끝. 이후 해당 브랜치에 코드를 푸시할 때마다 자동으로 재배포됩니다.
Part 3: Next.js (SSR) 프로젝트 배포
Option A: AWS Amplify
Next.js의 SSR, ISR, API Routes 등 모든 기능을 완벽하게 지원하므로 가장 추천되는 방법입니다.
- 과정은 React의 Amplify 배포와 동일합니다. Amplify가 Next.js 프로젝트임을 감지하고 서버사이드 렌더링을 위한 Lambda@Edge, API Routes를 위한 API Gateway 등을 자동으로 구성해줍니다.
Option B: Amazon ECS (Fargate) + Docker
서버가 계속 실행되어야 하는 Next.js의 특성상 EC2 또는 컨테이너 기반 배포가 필요합니다. ECS Fargate는 서버리스 컨테이너 실행 환경으로, EC2 인스턴스 관리가 필요 없습니다.
1. Dockerfile 작성
# 1. 빌드 환경
FROM node:18-alpine AS builder
WORKDIR /app
COPY package*.json ./
RUN npm install
COPY . .
RUN npm run build
# 2. 프로덕션 환경
FROM node:18-alpine AS runner
WORKDIR /app
COPY --from=builder /app/.next ./.next
COPY --from=builder /app/node_modules ./node_modules
COPY --from=builder /app/package.json ./package.json
EXPOSE 3000
CMD ["npm", "start"]
2. ECR에 이미지 푸시
- Spring Boot와 동일한 과정으로 이미지를 빌드하고 ECR에 푸시합니다.
3. ECS 클러스터, 작업 정의, 서비스 생성
- 클러스터 생성: 'ECS' > '클러스터' > '네트워킹 전용(AWS Fargate)' 선택.
- 작업 정의 생성:
- 컨테이너 추가 > ECR에 푸시한 이미지 URI 입력.
- 포트 매핑:
3000 - CPU/메모리 할당.
- 서비스 생성:
- 생성한 클러스터와 작업 정의 선택.
- 로드 밸런서(ALB)를 연결하여 외부 요청을 컨테이너와 연결.
- 원하는 작업 개수(컨테이너 수) 설정 및 오토 스케일링 구성.
Part 4: React Native 앱 배포
React Native는 모바일 앱이므로 AWS에 "배포"하는 개념이 다릅니다. 사용자의 기기에 설치되는 앱 자체는 App Store/Play Store를 통해 배포됩니다. AWS는 주로 앱의 백엔드 서버와 빌드/테스트 자동화를 위해 사용됩니다.
1. 백엔드 API 서버 배포
- React Native 앱이 통신할 API 서버가 필요합니다.
- 이 서버는 Part 1 (Spring Boot) 또는 Part 3 (Next.js API Routes)에서 설명한 방법으로 AWS에 배포합니다.
2. AWS CodePipeline을 이용한 CI/CD
- Git에 코드를 푸시하면 자동으로
ipa(iOS),aab(Android)파일을 빌드하고 테스트하는 파이프라인을 구축할 수 있습니다. - 소스:
GitHub등 리포지토리 연결. - 빌드:
AWS CodeBuild사용.buildspec.yml파일을 프로젝트에 추가하여 빌드 명령어를 정의합니다.- 예시 (
buildspec.yml일부):version: 0.2 phases: install: runtime-versions: nodejs: 18 pre_build: commands: - npm install build: commands: - cd android && ./gradlew bundleRelease artifacts: files: - android/app/build/outputs/bundle/release/app-release.aab
- (선택) 배포: 빌드된 파일을 S3에 저장하거나, Fastlane과 연동하여 App Store/Play Store에 자동으로 업로드할 수 있습니다.
Part 5: 공통 서비스 및 모범 사례
IAM (Identity and Access Management)
- 절대 Root 계정을 사용하지 마세요.
- 서비스별/목적별로 최소한의 권한을 가진 IAM 사용자와 역할을 생성하여 사용하세요.
- 예: S3 업로드만 가능한 사용자, EC2 읽기만 가능한 역할 등.
Route 53
- AWS의 DNS 서비스입니다. 구매한 도메인을 CloudFront, ALB, EC2 등에 연결할 수 있습니다.
- '호스팅 영역' 생성 후, 도메인 등록 기관(가비아 등)에서 네임서버를 Route 53의 네임서버로 변경합니다.
ACM (AWS Certificate Manager)
- CloudFront 또는 Application Load Balancer(ALB)에 연결할 수 있는 무료 SSL/TLS 인증서를 발급해줍니다.
- Route 53으로 DNS를 관리하면 인증서 발급 및 갱신이 매우 간단합니다.
비용 관리
- AWS는 사용한 만큼 비용을 지불하는 종량제입니다.
- 'Billing & Cost Management' 대시보드에서 비용을 주기적으로 확인하세요.
- 예상치 못한 비용 발생을 막기 위해 'Budgets'에서 예산을 설정하고 초과 시 알림을 받도록 설정하는 것이 좋습니다.