2025년 11월 24일 월요일 (121일차)

Jeonghoon·2025년 11월 24일

jeonghoon's Study

목록 보기
124/128

☁️ AWS Spring + React 통합 및 자동 배포 가이드

이 문서는 Spring Boot(백엔드)와 React(프론트엔드)를 하나의 프로젝트로 통합하여 빌드하고, Github Actions를 통해 자동 배포하는 과정을 설명합니다.


1. 🛠️ Spring + React 환경 구성 (build.gradle)

Spring Boot가 빌드될 때 React 프로젝트도 함께 빌드하여, 최종적으로 Spring의 static 리소스에 포함시키는 과정입니다. 이렇게 하면 별도의 웹 서버(Nginx 등) 없이 Spring Boot 서버 하나만으로 프론트와 백엔드를 모두 서비스할 수 있습니다.

[Image of Spring Boot React architecture]

📋 build.gradle 설정 (Groovy)

가장 먼저 com.github.node-gradle.node 플러그인이 추가되어 있어야 아래 Task들을 사용할 수 있습니다.

plugins {
    id 'java'
    id 'org.springframework.boot' version '3.x.x'
    id 'io.spring.dependency-management' version '1.x.x'
    // Node.js 사용을 위한 플러그인 필수 추가
    id "com.github.node-gradle.node" version "7.0.0" 
}

// --- React 빌드 설정 ---

def reactAppDir = "${project.projectDir}/src/main/reactapp"

// 1. npm install: React 의존성 설치
task npmInstallReact(type: NpmTask) {
    description = "Install Node.js dependencies from package.json"
    workingDir = file(reactAppDir)
    args = ['install']
    inputs.file("${reactAppDir}/package.json")
    inputs.file("${reactAppDir}/package-lock.json") 
    outputs.dir("${reactAppDir}/node_modules")
}

// 2. npm run build: React 앱 빌드 (프로덕션 모드)
task npmBuildReact(type: NpmTask) {
    description = "Build the React application using npm run build"
    dependsOn npmInstallReact
    workingDir = file(reactAppDir)
    args = ['run', 'build']
    
    inputs.dir("${reactAppDir}/src")
    inputs.dir("${reactAppDir}/public")
    inputs.file("${reactAppDir}/package.json")
    
    // ⚠️ Vite 사용 시 'dist', CRA(Create-React-App) 사용 시 'build' 확인 필수
    outputs.dir("${reactAppDir}/dist") 
}

// 3. Copy Task: 빌드된 리액트 결과물을 스프링의 정적 리소스 폴더로 복사
task copyReactBuild(type: Copy) {
    description = "Copy React build output to Spring Boot static resources"
    dependsOn npmBuildReact
    
    // 리액트 빌드 산출물 위치 (Vite: dist / CRA: build)
    from "${reactAppDir}/dist"
    // 스프링 부트가 정적 파일을 읽는 위치
    into "${project.buildDir}/resources/main/static"
}

// 4. Task 의존성 연결: 스프링 빌드 시 리액트 빌드 선행
processResources {
    dependsOn copyReactBuild
}

// 5. Clean Task: 빌드 아티팩트 정리
clean {
    delete file("${reactAppDir}/node_modules")
    delete file("${reactAppDir}/dist") 
}

💡 Key Point

  • 포트 통합: 개발 시에는 Spring(8080)과 React(5173)가 따로 돌지만, 배포 후에는 Spring(80) 하나로 통합됩니다.
  • API 요청: 로컬 개발 시 setupProxy.js 등을 썼다면, 배포 후에는 같은 도메인을 쓰므로 별도 설정 없이 /api/...로 요청하면 됩니다.

2. 🔄 CI / CD (지속적 통합 / 지속적 배포)

현대적인 개발 환경에서는 코드를 수정할 때마다 수동으로 빌드하고 FTP로 올리지 않습니다. 이 과정을 자동화하는 것이 CI/CD입니다.

개념전체 이름설명
CIContinuous Integration
(지속적 통합)
개발자가 코드를 git push 할 때마다 자동으로 **빌드(Build)하고 테스트(Test)**하여 코드의 오류를 조기에 발견하는 과정입니다.
CDContinuous Delivery/Deployment
(지속적 제공/배포)
테스트가 통과된 코드를 자동으로 운영 서버(AWS EC2 등)에 배포하여 사용자가 즉시 사용할 수 있게 만드는 과정입니다.

3. 🐙 Github Actions

Github에서 제공하는 CI/CD 자동화 도구입니다. 별도의 서버 구축(Jenkins 등) 없이 리포지토리에 설정 파일(.yaml)만 추가하면 바로 사용할 수 있습니다.

🚀 주요 흐름 (Workflow)

  1. Event 감지: 개발자가 main 브랜치에 git push를 합니다.
  2. 가상 환경 실행: Github Actions가 우분투(Ubuntu) 컨테이너를 띄웁니다.
  3. Checkout: 코드를 내려받습니다.
  4. Build: 위에서 설정한 build.gradle을 실행하여 Spring+React를 빌드합니다.
  5. Deploy: 빌드된 .jar 파일을 AWS EC2 등으로 전송하고 실행합니다.

📝 활용 예시

  • push 뿐만 아니라 Pull Request가 생성될 때 테스트를 돌려볼 수도 있습니다.
  • AWS S3, Docker Hub 등 다양한 환경으로 배포가 가능합니다.

0개의 댓글