Spring Framework

[SpringBoot] SpringBoot + React ๋นŒ๋“œ ๋ฐ ๋ฐฐํฌ ๊ณผ์ •

soogoori 2023. 11. 2. 18:17

 

์Šคํ”„๋ง๋ถ€ํŠธ์— ๋ฆฌ์•กํŠธ๋ฅผ ์—ฐ๋™์‹œํ‚ค๋Š” ๊ณผ์ •๊นŒ์ง€๋Š” ๊ทธ ์ „์— ์ง„ํ–‰ ์™„๋ฃŒ.

๋นŒ๋“œ์™€ ๋ฐฐํฌํ•˜๋Š” ๊ณผ์ • ๊ธฐ๋ก. 

 

๋ฐฐํฌํ•  ์ƒ๊ฐ์ด ์—†์—ˆ๋Š”๋ฐ ํ•ด์•ผํ•˜๋Š” ์ƒํ™ฉ์ด ์™”๊ธฐ์— ์ƒ๋‹นํžˆ ๋ฌด์‹ํ•œ ๋ฐฉ๋ฒ•์œผ๋กœ ์ง„ํ–‰ํ–ˆ๋‹ค..

๊ทธ๋ƒฅ ๋ณ„๋‹ค๋ฅธ ์„ค์ • ์•ˆํ•˜๊ณ  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ํฌํŠธ๋กœ ์ž˜๋ชป ์ ์—ˆ๋‹ค.. 

 

๋”๋ณด๊ธฐ

๋‹ค์‹œ ์ƒ๊ฐํ•ด๋ณด๋ฉด ์‚ฌ์†Œํ•œ ๊ฒƒ๋“ค์—์„œ ์‹œ๊ฐ„์„ ์žก์•„๋จน์€ ๊ฒƒ ๊ฐ™๋‹ค ๐Ÿฅฒ

 

 

์ฐธ๊ณ 

๋”๋ณด๊ธฐ