-
Springboot(Maven), React, MySQL 프로젝트 Heroku 배포하기Spring 2021. 11. 5. 22:06
웹 앱에 대한 서버와 프론트엔드 (rest api로 프록시를 설정해서 연결 완료) 개발을 완료했다면,
이제 데이터 베이스와 함께 앱 배포를 해야한다.
(여기서 거진 5일을 소비했다...^^)
개발 겨우 다해놨는데 외않되,,,?ㅎ
이러한 사태를 방지하기 위해서 꼭 애초에 프로젝트 구성을 잘 짜는 것이 중요하다.
프로젝트를 프론트엔드, 백엔드 따로따로 모두 완성해서 다른 포트에 실행하는 상태라면
다음의 순서대로 배포해보자.
frontend를 backend 폴더 안으로 옮겨주기
이 프론트엔드를 백엔드로 옮겨주기란 것은 다음과 같이 인텔리제이로 완성된 백엔드앱 안에 프론트 엔드를 넣어주는 것이다.
📦APP
├── 🗂backend
│ ├── src
├── 🗂frontend
처음의 이러한 구조에서
📦APP
├── 🗂backend
│ ├── 🗂frontend
│ ├── src
이러한 구조로 안에 넣어주면 되는데, 여기서 frontend를 옮길 때에는 public, src, package.json만 옮겨주고 해당 폴더로 이동한 뒤 npm install을 통해 재설정해준다.
(애초에 설정할 것이면 backend 폴더로 가서 npx create-react-app frontend 해주면 된다)
이후 꼭 변경된 폴더에서 npm build가 성공적으로 실행되는지 확인하고 만약 여기서 Unknown browser query 'dead' in React/Express App 에러가 발생한다면, package.json안의 "not dead"부분을 삭제해준다.
"browserslist": { "production": [ ">0.2%", //이부분을 삭제 "not dead", "not op_mini all" ],
추가로 package.json에 proxy 설정은 되어있어야 한다. (rest-api개발을 완료했다면 다 설정이 되어있겠지만)
Frontend-maven-plugins Dependency 추가
이제 리액트와 스프링부트를 패키징 할 수 있는 dependency를 추가해준다.
<properties> <java.version>11</java.version>//사용 자바버전 입력 </properties> <build> <plugins> <plugin> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-maven-plugin</artifactId> <configuration> <excludes> <exclude> <groupId>org.projectlombok</groupId> <artifactId>lombok</artifactId> </exclude> </excludes> </configuration> </plugin> <plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-surefire-plugin</artifactId> <configuration> <excludes> //<exclude>**/*.java</exclude>입력 </excludes> </configuration> </plugin> <plugin> <groupId>com.github.eirslett</groupId> <artifactId>frontend-maven-plugin</artifactId> <version>1.12.0</version>//최신 버전을 써주도록 하자. <configuration> <workingDirectory>frontend</workingDirectory> <installDirectory>target</installDirectory> </configuration> <executions> <execution> <id>install node and npm</id> <goals> <goal>install-node-and-npm</goal> </goals> <configuration> //이곳의 노드 버전과 npm 버전은 자신이 개발한 환경에서 사용한 버전과 일치해야한다. <nodeVersion>v16.1.0</nodeVersion> <npmVersion>7.11.2</npmVersion> </configuration> </execution> <execution> <id>npm install</id> <goals> <goal>npm</goal> </goals> <configuration> <arguments>install</arguments> </configuration> </execution> <execution> <id>npm run build</id> <goals> <goal>npm</goal> </goals> <configuration> <arguments>run build</arguments> </configuration> </execution> </executions> </plugin> </plugins> </build>
여기서 frontend-maven-plugins의 최신 버전은 다음에서 확인할 수 있다.
https://github.com/eirslett/frontend-maven-plugin
node버전과 npm 버전은 터미널에 node --version, npm --version을 입력해서 확인해주자.
입력을 완료했다면
./mvnw clean install
을 입력해서 빌드를 완성해준다.
JAR파일 안에 frontend 빌드를 포함시키는 Dependency 추가
이제 스프링부트의 .jar파일 실행시 frontend도 함께 빌드해주는 dependency를 추가하자.
<plugin> <artifactId>maven-antrun-plugin</artifactId> <executions> <execution> <phase>generate-resources</phase> <configuration> <target> //빌드를 어디다 할 지 설정 <copy todir="${project.build.directory}/classes/public"> //어느 파일을 빌드할 지 설정 <fileset dir="${project.basedir}/frontend/build"/> </copy> </target> </configuration> <goals> <goal>run</goal> </goals> </execution> </executions> </plugin>
이후 동일하게
./mvnw clean install
이 target폴더안에 jar파일이 생성된 것도 확인할 수 있다.
Jar 파일 실행여부 확인하기
이제 완성된 .JAR파일을 실행시켜서 동일하게 작동하는지 확인해주자.
java -jar target/생성된 자바 jar파일 이름.jar
터미널에 실행시키면 각각 프로그램을 실행시켰을 때와 동일하게 localhost:8080포트로 잘 작동하는 것을 확인할 수 있다.
Heroku 설정 해주기
여기까지만 heroku create <앱이름> 해서 git push heroku origin 을 통해 deploy를 했는데, Failed to execute goal org.apache.maven.plugins:maven-compiler-plugin:3.8.1:compile (default-compile) on project invalid target release: 11 가 발생했다.
해당 오류 검색해서 찾아보니 헤로쿠의 자바버전과 내가 사용하려는 버전이 일치하지 않기 때문에 발생하는 오류였다.
그래서 검색해서
<plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-compiler-plugin</artifactId> <version>메이븐버전</version> <configuration> <source>자바버전</source> <target>자바버전</target> </configuration> </plugin>
넣으래서 했는데도 안됨.
<properties> <maven.compiler.source>자바버전</maven.compiler.source> <maven.compiler.target>자바버전</maven.compiler.target> </properties>
안됨.
해당 원인을 찾았는데 바로 헤로쿠 설정을 제대로 하지 않아서였다.
https://stackoverflow.com/questions/53604111/heroku-cannot-deploy-java-11-spring-boot-app
java.runtime.version=11
애초에 이 런타임 버전 설정을 application.properties에 작성해 놓은 것이다. (바보바보바보바보바보)
해당 프로젝트의 최상위 폴더에 (.jar파일들어있는 프로젝트 안에) system.propterties를 만들어주고 그 안으로 해당 내용을 옮겨주자.
📦APP
├── 🗂backend
│ ├── src
├── 🗂frontend
├── system.propteries
추가로 헤로쿠가 해당 내용을 실행할 때, .jar파일을 실행할 수 있도록 설정을 해주자.
이 설정에는 Procfile파일을 만들어서 설정을 지정해주거나, heroku config를 통해서 PATH_TO_JAR를 설정해주는 방법이 있다.
① Procfile만들기
최상위 폴더에 (.jar 파일 들어있는 프로젝트 안에) Procfile을 만들어주고 해당 내용을 입력해준다.
web: java -Dserver.port=$PORT $JAVA_OPTS -jar target/jar파일 이름.jar
📦APP
├── 🗂backend
│ ├── src
├── 🗂frontend
├── system.propteries
├── Procfile
② heroku config 지정하기
터미널에 다음과 같이 입력해준다.
heroku config:set PATH_TO_JAR=프로젝트이름(여기선 backend)/target/jar파일이름.jar
설정을 완료하고 헤로쿠로 가보면,
jar 파일 설정이 완료된 것을 확인할 수 있다.
배포 전 Proxy URL 설정
리액트와 스프링부트를 진행했다면, oAuth2 redirect uri나 react-proxy 설정 등등 에 http://localhost:8080으로 설정이 되어 있을 텐데, 모두 헤로쿠 https://헤로쿠 앱이름.com.herokuapp.com으로 바꿔주어야 설정에 오류 없이 작동할 것이다.
특히 sockJS를 이용해서 socket을 사용하고 있다면
var sock = new SockJS('https://헤로쿠 앱이름.com.herokuapp.com/chat')
으로 바꿔주도록 하자.
(설정해 주지 않으면 흰 백지창이 나오면서 socket connection timeout 에러가 발생하게 될 것이다. )
...
MySQL 연동
이제 터미널에서 git push heroku master를 완료해주면 Application Fail이 나올 것이다.
DB를 연결해주지 않았기 때문이다.
먼저 헤로쿠의 clearDB 사용해서 배포 할 것이기 때문에 헤로쿠에 결제카드를 등록해주자. (카드 등록해줘야 무료버전을 사용할 수 있다)
https://elements.heroku.com/addons/cleardb
카드등록을 마치고 해당 터미널에서 다음과 같이 추가해준다. (ignite가 무료버전이다)
heroku addons:create cleardb:ignite -a 해로쿠앱이름
heroku addons로 확인해보면 cleardb가 추가된 것을 확인할 수 있다.
헤로쿠로 가보면 다음과 같이 cleardb가 설치된 것을 알 수 있다.
해당 db를 눌러서 정보를 확인하면 username, password를 확인할 수 있다.
이제 생성된 db정보를 확인해보자.
heroku run -a 해로쿠앱이름 printenv
위와 같이 검색하면 우리가 설정한 부분들을 모두 확인할 수 있는데, 여기서 출력된 CLEARDB_DATABASE_URL에 집중하자.
mysql://Username:Password@Host/DefaultSchema?~~
해당 URL은 위와 같은 구조로 되어있다.
이제 MySQL Workbench를 통해서 이미 구성해놨던 데이터 베이스를 집어 넣어주자.
Manage Connection창으로 들어가서 아까 읽었던 정보들을 입력해주고 (host, username, default schema) test connection하면 password 입력창이 나오게 된다. 아까 cleardb의 password를 입력해주면 workbench에 지정해준 이름의 connection이 생성된 것을 확인할 수 있다.
워크벤치의 server -> data export, data import를 사용할 것이다.
이미 설정했던 mysql의 커넥션으로 가서 해당 프로젝트 데이터를 data export 해준다.
생성된 .sql파일을 아까 지정했던 헤로쿠 cleardb connection으로 가서 import를 해줄 것이다.
그런데 여기서 그대로 import하려면 에러가 발생한다.
생성된 sql에서의 @@character_set_database, @@collation_database가 해당 타입과 맞지 않기 때문이다.
저장된 sql파일을 열어서 utf8mb4부분을 모두 utf8로, COLLATE-utf8mb4_0900_ai_ci부분을 utf8_general_ci로 모두 replace all 해준다.
변경후 데이터 Data-Import(Import from Self-contained File)를 해주면 이전에 설정했던 데이터가 모두 잘 들어간 것을 확인 할 수 있다.
Heroku open
heroku open
터미널에 헤로쿠 오픈을 실행해주면 db연결이 완성되면서 잘 작동하는 것을 확인할 수 있다.
(참고한 사이트)
https://sundries-in-myidea.tistory.com/71
https://rocksea.tistory.com/345
'Spring' 카테고리의 다른 글
Data too long for column 오류 발생시 (0) 2021.11.06 Amazon S3를 이용해서 파일 저장, 삭제하기 (0) 2021.11.05 SMTP 서버를 통한 이메일 보내기 (0) 2021.10.26 OAuth2 사용해서 react와 함께 소셜로그인 기능 만들기 (4) 2021.10.26 TDD (Test Driven Development) : 단위 테스트 작성하기 (0) 2021.10.26