[AWS] React + Spring Boot(Maven) 프로젝트 AWS EC2(Ubuntu)에 빌드 및 배포하기

2025. 5. 12. 13:05·AWS

프로젝트 개발이 어느 정도 끝나서 내가 빌드 배포를 맡게 되어서 진행하게 되었다. 간단한 프로젝트여서 도커 사용 없이 빌드 배포하는 방법을 선택했고, Maven 프로젝트이며 EC2는 우분투 환경으로 인스턴스를 만들었다. DB는 기존에 EC2 안에 설치해두었기 때문에 따로 할 필요는 없었다. React 애플리케이션을 먼저 빌드하여 Spring Boot의 정적 리소스 폴더에 통합한 후, 단일 JAR 파일로 배포하는 방식을 다룬다. 배포 과정에서 발생할 수 있는 문제점들과 해결 방법도 함께 안내한다.

 

 

1. 초기 빌드 및 배포 과정

1-1. React 빌드 자동화 설정

React 프로젝트에서 빌드 후 자동으로 Spring Boot의 static 폴더로 파일을 복사하도록 설정한다. package.json 파일에 다음 스크립트를 추가한다.

"postbuild": "xcopy /s /y build\\* C:\\javaStudy\\workspace_boot\\IDEA-backend\\src\\main\\resources\\static\\"

 

이 설정을 통해 npm run build 명령어 실행 시 React 빌드가 완료된 후 자동으로 Spring Boot의 static 폴더로 빌드 파일들이 복사된다.

 

1-2. Spring Boot 프로젝트 빌드

React 빌드 파일들이 통합된 상태에서 Spring Boot 프로젝트를 빌드한다. IDE(이클립스 등)를 사용하여 clean package 명령을 실행하거나, 터미널에서 다음 명령어를 실행한다.

 

  • 터미널에서 빌드 안할 경우

      1. 프로젝트를 우클릭 → Run As → Maven clean 선택

 

        2. Maven clean이 완료되면 다시 프로젝트를 우클릭 → Run As → Maven build 선택

 

 

      3. Goals 입력창에 "package" 입력 후 실행

 

  • 터미널에서 빌드하는 경우
mvn clean package

 

빌드가 완료되면 target 폴더에 프로젝트명-버전.jar 파일이 생성된다.

 

1-3. AWS EC2로 파일 업로드

Windows 환경에서 SCP 명령어를 사용하여 JAR 파일을 EC2 인스턴스로 업로드한다.

scp -i "경로/키파일명.pem" "경로/프로젝트명-버전.jar" ubuntu@EC2-IP주소:/home/ubuntu/

예시:

scp -i "C:\javaStudy\idea.pem" "C:\javaStudy\workspace_boot\IDEA-backend\target\idea-backend-0.0.1-SNAPSHOT.jar" ubuntu@3.38.213.53:/home/ubuntu/

 

1-4. EC2 환경 설정 및 실행

EC2 인스턴스(Ubuntu)에 SSH로 접속한다.

ssh -i "경로/키파일명.pem" ubuntu@EC2-IP주소

 

먼저 업로드된 파일을 확인한 후, JDK를 설치한다.

# 업로드된 파일 확인
ls -la /home/ubuntu/

# 시스템 업데이트
sudo apt update

# JDK 17 설치
sudo apt install openjdk-17-jdk -y

# 자바 버전 확인
java -version

 

어플리케이션을 백그라운드에서 실행한다. 이때 메모리 제한을 설정하여 시스템 리소스를 효율적으로 관리한다.

  • nohup: SSH 연결이 끊어져도 프로세스가 계속 실행되도록 함
  • -Xmx512m: 최대 힙 메모리를 512MB로 제한
  • > app.log 2>&1 &: 로그 파일로 출력을 저장하고 백그라운드에서 실행
# 512MB 메모리 제한으로 백그라운드 실행
nohup java -Xmx512m -jar 프로젝트명-버전.jar > app.log 2>&1 &

 

실행 상태를 확인하고 로그를 모니터링한다.

# 실행 프로세스 확인
ps aux | grep java

# 로그 실시간 확인
tail -f app.log

 

 

2. 재배포 과정

코드를 수정한 후 재배포할 때는 다음 과정을 따른다.

 

2-1. 기존 어플리케이션 종료

EC2에 접속한 상태에서 실행 중인 Java 프로세스를 종료한다. 일반적인 종료 명령으로 프로세스가 종료되지 않을 경우, 프로세스 ID를 확인하여 강제 종료할 수 있다.

# 실행 중인 Java 프로세스 확인
ps aux | grep java

# Java 프로세스 종료 시도
pkill -f "java -jar"

# 위 명령어로 종료되지 않는 경우, 프로세스 ID를 확인하고 강제 종료
# 예: PID가 21609인 경우
kill -9 21609

 

2-2. 로컬 환경으로 복귀

EC2 세션을 종료하고 로컬 환경으로 돌아간다.

exit

 

2-3. 빌드 및 업로드

로컬에서 다시 빌드 과정을 수행한다.

# React 빌드 (자동으로 Spring Boot static 폴더에 복사됨)
npm run build

# Spring Boot 빌드
clean package

 

빌드된 새로운 JAR 파일을 EC2로 업로드한다.

scp -i "경로/키파일명.pem" "경로/새로운-프로젝트명-버전.jar" ubuntu@EC2-IP주소:/home/ubuntu/

 

2-4. 어플리케이션 재실행

다시 EC2에 접속하여 새로운 JAR 파일을 실행한다.

ssh -i "경로/키파일명.pem" ubuntu@EC2-IP주소
nohup java -Xmx512m -jar 프로젝트명-버전.jar > app.log 2>&1 &

 

 

3. 배포 과정에서 마주친 오류와 해결과정

3-1. .pem 파일 권한 오류

Windows에서 .pem 파일 권한 오류가 발생할 때 다음과 같이 해결했다.

 

1. 파일 탐색기에서 .pem 파일 우클릭 → 속성 → 보안 → 고급으로 이동한다.

 

2. "상속 사용 안 함"을 선택하여 모든 상속 권한을 제거한다.

 

이때 보안 안내가 뜨면 "예"를 선택한다.

 

그러면 사용 권한 목록이 모두 빈 상태가 되며, "확인"을 선택한다.

 

그룹 또는 사용자 이름 항목들도 모두 빈 상태가 되면 "편집"을 선택한다.

 

.pem의 사용 권한 창이 뜨면 "추가" 버튼을 선택한다.

 

사용자 또는 그룹 선택에서 개체 유형, 위치, 개체 이름을 선택 및 입력해야 한다. 개체 유형은 사용자만 선택하고 개체 이름은 컴퓨터 계정명을 입력하고 "이름 확인"을 눌러서 확인해야 한다. 만약 컴퓨터 계정명이 아닌 다른 것을 입력하면 "이름을 확인할 수 없다"고 하므로 주의해야 한다.

 

이 과정까지 끝내고 다시 .pem 키를 이용하여 JAR 파일을 EC2 인스턴스로 업로드할 수 있었다.


3-2. CORS 오류

빌드 배포가 끝나고 주소창에 접속하니 데이터를 불러올 수 없다는 오류가 발생했다. 이유는 백엔드와 프론트엔드에 배포된 주소로 입력하지 않아서 발생한 것이었다. 백엔드에서 CORS mapping 관련 코드를 수정하고 프론트엔드의 .env 파일에서 경로를 수정한 후 빌드 및 배포를 다시 하니 정상적으로 완료되었다.

@Override
	public void addCorsMappings(@NonNull CorsRegistry registry) {
		registry.addMapping("/**")
			.allowedOriginPatterns("http://localhost:3000", "http://localhost:8000", "http://EC2-IP주소:포트번호")
			.allowedMethods("GET", "POST", "PUT", "DELETE", "OPTIONS","PATCH")
			.allowedHeaders("*")
			.exposedHeaders("Authorization")
			.allowCredentials(true);
	}
# 로컬
# REACT_APP_API_URL=http://localhost:포트번호

# 배포
REACT_APP_API_URL=http://EC2-IP주소:포트번호

 

 

마무리

이러한 빌드 배포 과정을 거치면서 성공적으로 React와 Spring Boot 애플리케이션을 AWS EC2에 배포할 수 있었다. 특히 흔히 알고 있는 도커 사용, 프록시 사용, 도메인 사용 등의 방법을 사용하지 않아서 복잡한 CI/CD 파이프라인 구축 없이도 안정적으로 서비스를 배포할 수 있어, 클라우드 배포를 처음 시도하는 개발자에게도 적합한 방법이라고 생각한다.

다음에는 포트번호 없이 접속할 수 있도록 Nginx 리버스 프록시 설정을 적용하거나, 도메인을 연결하여 더 깔끔한 URL로 서비스를 제공해보고 싶다. 또한 도커를 사용한 컨테이너 기반 배포나 Jenkins를 활용한 자동화 배포 파이프라인 구축도 도전해볼 계획이다.

'AWS' 카테고리의 다른 글

[AWS] EC2에서 Nginx로 포트 번호 없이 웹 서비스 배포하기  (0) 2025.05.16
[AWS] Docker와 GitHub Actions를 활용한 CI/CD 파이프라인 구축과 환경 변수 문제 해결  (0) 2025.05.15
[AWS] Windows에서 AWS EC2까지: Docker로 Python 서비스 배포하기  (0) 2025.05.14
[AWS] EC2 서버 용량 문제 해결하기  (0) 2025.05.13
[AWS] EC2(Ubuntu)에 MySQL 설치하고 스프링부트와 연결하기  (0) 2025.04.25
'AWS' 카테고리의 다른 글
  • [AWS] Docker와 GitHub Actions를 활용한 CI/CD 파이프라인 구축과 환경 변수 문제 해결
  • [AWS] Windows에서 AWS EC2까지: Docker로 Python 서비스 배포하기
  • [AWS] EC2 서버 용량 문제 해결하기
  • [AWS] EC2(Ubuntu)에 MySQL 설치하고 스프링부트와 연결하기
dud9902
dud9902
개발자 취준생 기록일지
  • dud9902
    dud's DevStory
    dud9902
  • 전체
    오늘
    어제
    • 분류 전체보기 (79)
      • SpringBoot (14)
      • React (12)
      • Python (14)
      • AI (21)
      • DB (6)
      • Figma (1)
      • Markdown (1)
      • AWS (7)
      • 기타 (3)
  • 블로그 메뉴

    • 홈
    • 태그
    • 방명록
  • 링크

  • 공지사항

  • 인기 글

  • 태그

    스프링부트
    pytorch
    langchain
    db
    CrewAI
    AI
    react
    AWS
    Python
    springboot
    pydantic
    recognize anything
    redis
    FastAPI
    miniforge
    Agent
    twilio
    의존성 주입
    EC2
    docker
  • 최근 댓글

  • 최근 글

  • hELLO· Designed By정상우.v4.10.3
dud9902
[AWS] React + Spring Boot(Maven) 프로젝트 AWS EC2(Ubuntu)에 빌드 및 배포하기
상단으로

티스토리툴바