[Tistory] [SpringBoot] SpringBoot + React 빌드 및 배포 과정

원글 페이지 : 바로가기

스프링부트에 리액트를 연동시키는 과정까지는 그 전에 진행 완료. 빌드와 배포하는 과정 기록. 배포할 생각이 없었는데 해야하는 상황이 왔기에 상당히 무식한 방법으로 진행했다.. 그냥 별다른 설정 안하고 EC2 인스턴스에 서버 띄우는 정도만.. 물론 이것도 배포의 한 과정이긴 하지만.. 그래도 이틀동안 고민하면서 하긴 했으니깐 기록한다. 📍 빌드 & 배포 과정 1. 리액트 & 스프링부트 통합 빌드 (Gradle) 2. 배포 (EC2 인스턴스에 서버 띄우기) 2-1. MySQL 로컬에서 EC2로 dump .. ⭐️ 🔴 통합 빌드하기 스프링부트를 실행시키고, 리액트를 npm start로 따로 실행시켰는데 한번에 실행시키기 위해 통합 빌드를 한다. 우선 디렉토리 구조는 이러하다. 통합 빌드시키기 전에 frontend 폴더가 프로젝트 경로 바로 아래에 위치해있었는데, 스프링 프로젝트 내부로 옮겨야 된다는 소리가 있어서 /src/main으로 옮겨주었다. 인텔리제이 내부에서 리액트 폴더를 드래그해서 옮겨주면 맥북이 엄청 뜨거워지며, 인텔리제이 CPU가 600%나 차지하게 되니깐…. 그냥 파인더에서 폴더를 옮겨야한다… 🔹 리액트 설정 package.json에 proxy 설정을 해준다. 나중에 배포할 시에는 localhost를 다른 걸로 바꿔주었다. 🔹 build.gradle 설정 def frontendDir = “$projectDir/src/main/frontend”

sourceSets {
main {
resources { srcDirs = [“$projectDir/src/main/resources”]
}
}
}

processResources { dependsOn “copyReactBuildFiles” }

task installReact(type: Exec) {
workingDir “$frontendDir”
inputs.dir “$frontendDir”
group = BasePlugin.BUILD_GROUP
if (System.getProperty(‘os.name’).toLowerCase(Locale.ROOT).contains(‘windows’)) {
commandLine “npm.cmd”, “audit”, “fix”
commandLine ‘npm.cmd’, ‘install’ }
else {
commandLine “npm”, “audit”, “fix” commandLine ‘npm’, ‘install’
}
}

task buildReact(type: Exec) {
dependsOn “installReact”
workingDir “$frontendDir”
inputs.dir “$frontendDir”
group = BasePlugin.BUILD_GROUP
if (System.getProperty(‘os.name’).toLowerCase(Locale.ROOT).contains(‘windows’)) {
commandLine “npm.cmd”, “run-script”, “build”
} else {
commandLine “npm”, “run-script”, “build”
}
}

task copyReactBuildFiles(type: Copy) {
dependsOn “buildReact”
from “$frontendDir/build”
into “$projectDir/src/main/resources/static”
} build.gradle에 상단의 스크립트를 추가한다. 스크립트 내용은 frontendDir에 리액트 설치하고 뭐 npm run, build 하겠다 ~~ 이런 내용인 것 같다. 그리고 빌드한 내용이 resources/static에 옮겨진다. 파일 경로를 잘못 지정해서 배포되었음에도 화면이 제대로 나오지 않아서 애 먹었다.. ⛔️ 파일 경로를 항상 주의해야겠다.. Gradle ➔ build ➔ build, jar를 눌러서 jar 파일을 생성시키면 build 폴더 ➔ libs 폴더에 jar 파일이 생성된 것을 볼 수 있다. resources 폴더에도 잘 옮겨온 듯하다. 연결 완료 이제 npm start로 리액트를 따로 실행시키지 않아도 된다. ! 스프링부트를 실행시켜보면 localhost:3000이 아닌 localhost:8080으로 연결된 것을 확인할 수 있다. 🔴 배포하기 – EC2 인스턴스에 서버 띄우기 EC2 인스턴스 생성하는건 다른 블로그 글에서 잘 정리되어있기 때문에 생략. 인바운드 규칙만 주의해서 하면 된다. IPv6까지는 안해줘도 될 것 같다.. 중간중간 오류해결하려고 이것저것 해보다가 그냥 넣은거다.. 3000포트는 리액트 때문에 넣어주었다. 🔹 인스턴스 연결 인스턴스를 시작하고, 연결하려면 터미널 켜고 아래의 사진에 나와있는 것처럼 해주면 된다. 하지만 이대로 진행하면 매번 저 긴 ssh -i {키 페어 파일} {ubuntu}@{ec2 퍼블릭 주소} 를 입력해야한다. 이 귀찮은 작업을 호스트 등록을 통해 간편하게 접속할 수 있다. 🔸 호스트 등록 cp {key-pair-file-name.pem} ~./ssh/ 로 ~/.ssh 디렉토리로 키 페어 파일을 복사한 후 chmod 600 {key-pair-file-name.pem} 로 키 페어 파일 권한을 변경한다. ~/.ssh 디렉토리에 config 파일을 생성한 후 $ vi ~/.ssh/config

# 파일 내용
# ssh -i {키 페어 파일} {유저 이름}@{탄력적 IP}
Host {원하는 호스트 이름}
User {유저 이름}
HostName {탄력적 IP}
IdentityFile {키 페어 파일 위치} 위의 형식대로 작성해주면 된다. 설정한 Host 이름으로 접속하면 잘 연결된 것을 확인할 수 있다 ! 접속 완료 🔷 EC2 인스턴스에 SpringBoot 서버 띄우기 git clone해서 실행시키는 방법과 jar 파일 빌드해서 EC2에 복사한 후 실행시키는 방법이 있다고 한다. git을 사용하고 싶었지만… 이런저런 사정 때문에… 그냥 두번째 방법을 택했다. 1. JDK 설치 sudo 권한으로 apt 업데이트하고, java 버전에 맞게 설치한다. 17버전으로 진행했기 때문에 openjdk v17로 설치했다. # EC2 인스턴스
$ sudo apt-get update
$ sudo apt-get install openjdk-17-jdk 버전을 확인하면 이와 같다. 2. Spring Boot 프로젝트 build 프로젝트를 빌드하면 ./build/libs에 jar 파일이 생성된다. 이 파일을 EC2 서버로 복사해야한다. 호스트 이름에는 아까 위에서 설정한 호스트 이름을 넣던지, 아니면 ubuntu@{퍼블릭 IP 또는 DNS} 을 입력한다. 3. EC2 인스턴스에서 실행시키기 # EC2 인스턴스
$ nohup java -jar {jar 파일명}-0.0.1-SNAPSHOT.jar & 터미널 창을 꺼도 백그라운드에서 계속 실행시키기 위해서 nohup 명령어를 사용한다. 로그 파일은 nohup.out에 저장된다. 종료시키기 위해서는 sudo lsof -PiTCP -sTCP:LISTEN 명령어를 입력한 후 kill -9 {PID} 로 해당하는 PID를 죽이면 된다. 🔴 로컬에 있던 MySQL 데이터들을 EC2 서버 MySQL로 옮기기 위에서 말했다시피 배포를 전혀 할 생각이 없었기 때문에 이미 로컬에 있던 데이터들을 서버에 옮겨야 했다. 검색해보니 백업해서 뭐 어떻게 하라는데 사실 다른 방법이 있는지는 모르겠다. 🔷 로컬 mysqldump -u root -p –databases [db_name] > [db_name].sql [db_name].sql 파일이 생성되면서 이 파일을 EC2 서버로 옮겨주어야 한다. scp -i [pem_file_name] [upload_file] ubuntu@ec[ip_of_ec2]:~/[transfer_path] EC2 서버에 이동 완료 🔷 EC2 서버 mysql -u root -p
mysql> create database [db_name]
mysql> exit 복원할 DB를 생성한다. mysql -u root -p [db_name] < [db_name].sql 복사한 sql 파일을 생성한 DB에 복원하면 그대로 가져오게 된다.. ! 🔴 결과 짠 ! 데이터까지 잘 불러와졌다.. https를 따로 적용하지 않아서 '주의 요함'이 뜬다. 아직 할 생각이 없긴 하다.. 하긴 해야하는데.. 도메인은 예전에 구입했던 것을 사용할 예정이다. 추후에 추가해야지... 💢 오류 났던 것들.. its MIME type ('application/json') is not supported stylesheet MIME type, and strict MIME checking is enabled. ➔ 파일 경로 수정해서 해결. MySQL 서버 실행시키기.. ➔ 인바운드 규칙 편집을 통해서 해결. test connection 누르고 무지개 돌아갈 때마다 갑갑했다.. net::ERR_CONNECTION_REFUESED ➔ 리액트 3000 포트를 8080 포트로.. ➔ index.js에 퍼블릭 ip로 바꿔주면서 해결. net::ERR_CONNECTION_TIMED_OUT ➔ 8080포트를 8000포트로 잘못 적었다.. 더보기 다시 생각해보면 사소한 것들에서 시간을 잡아먹은 것 같다 🥲 참고 더보기 https://bcp0109.tistory.com/356 https://velog.io/@seyoung755/AWS-EC2%EB%A5%BC-%EC%9D%B4%EC%9A%A9%ED%95%B4-%EB%B0%B0%ED%8F%AC%ED%95%B4%EB%B3%B4%EC%9E%90-3-MySQL-%EC%84%9C%EB%B2%84-%EC%8B%A4%ED%96%89 https://jminie.tistory.com/101 https://velog.io/@codingmingu/Ubuntu-AWS-EC2-MySQL-%EC%84%9C%EB%B2%84%EA%B5%AC%EC%B6%95-%EC%99%B8%EB%B6%80%EC%A0%91%EC%86%8D-Unable-to-connect-to-localhost-%EC%98%A4%EB%A5%98%ED%95%B4%EA%B2%B0 https://maruzzing.github.io/study/etc/EC2(%EC%95%84%EB%A7%88%EC%A1%B4-%EB%A6%AC%EB%88%85%EC%8A%A4)%EC%97%90-%EC%84%9C%EB%B2%84%EC%99%80-DB(mysql)-%EB%B0%B0%ED%8F%AC%ED%95%98%EA%B8%B0-2/ https://velog.io/@matisse/AWS-%EC%82%AC%EC%9A%A9%ED%95%98%EA%B8%B0#--mysqldump https://repost.aws/ko/knowledge-center/ec2-linux-resolve-ssh-connection-errors https://mopil.tistory.com/59 https://mandykr.tistory.com/12 https://chordplaylist.tistory.com/272

답글 남기기

이메일 주소는 공개되지 않습니다. 필수 필드는 *로 표시됩니다