ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • 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

     

    GitHub - eirslett/frontend-maven-plugin: "Maven-node-grunt-gulp-npm-node-plugin to end all maven-node-grunt-gulp-npm-plugins." A

    "Maven-node-grunt-gulp-npm-node-plugin to end all maven-node-grunt-gulp-npm-plugins." A Maven plugin that downloads/installs Node and NPM locally, runs NPM install, Grunt, Gulp and/or Kar...

    github.com

    node버전과 npm 버전은 터미널에 node --version, npm --version을 입력해서 확인해주자. 

     

    입력을 완료했다면 

    ./mvnw clean install

     

    을 입력해서 빌드를 완성해준다. 

     

    백엔드 안의 프론트엔드에 build가 완성된 것을 확인할 수 있다. 

     

     

     

    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/classes/public폴더 안에 동일하게 build된 것을 확인할 수 있다. 

    이 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>

    넣으래서 했는데도 안됨.

    2차 빡침

    <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

     

    Heroku cannot deploy Java 11 Spring Boot App

    I am trying to deploy a Spring Boot app on Heroku ,using Java version 11.0.1. The error: Failed to execute goal org.apache.maven.plugins:maven-compiler-plugin:3.8.0:compile (default-compile) on p...

    stackoverflow.com

    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

     

    ClearDB MySQL - Add-ons - Heroku Elements

     

    elements.heroku.com

     

     

    카드등록을 마치고 해당 터미널에서 다음과 같이 추가해준다. (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가 해당 타입과 맞지 않기 때문이다. 

     

    mysql 의 정보

    저장된 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

     

    Spring Boot와 React를 연동하여 개발환경을 만들어보자

    이글을 읽어보기전에!! 한번 고려해볼 점을 제가 적어뒀습니다 한번 참고 해보고 프로젝트를 진행해주세요! [Java/Spring] - Spring Boot와 React를 통한 개발환경을 구성할때 고민해볼점 Spring Boot와 React

    sundries-in-myidea.tistory.com

     

    https://rocksea.tistory.com/345

     

    [Heroku] Getting started with Heroku

    Paas 클라우드 서비스 Heroku 시작하기. 클라우드서비스가 대중적이지 않던 시절에는 SE나 개발자가 인프라를 구축하고 운영해야 했으나, 요즘과 같이 다양한 클라우드 인프라를 이용할 수 있는

    rocksea.tistory.com

    https://velog.io/@chyin370/ToyProject-%EB%8D%B0%EC%9D%B4%ED%84%B0%EB%B2%A0%EC%9D%B4%EC%8A%A4-%EC%84%A4%EC%A0%95

     

    [wisestudy] 데이터베이스 설정

    JPA/Hibernate와 MySQL 데이터베이스를 연결하는 과정입니다.

    velog.io

    https://jungguji.github.io/2021/01/28/Spring-boot-Heroku%EC%97%90-%EB%B0%B0%ED%8F%AC%ED%95%98%EA%B8%B0/

     

    Spring boot Heroku에 배포하기

    서론AWS 프리티어는 이미 다른 서비스가 이용하고 있고 Java를 지원해주는 클라우드 서비스가 없었는데 heroku를 발견하여 사용방법을 정리 해둔다. 참고로 데이터베이스는 한글을 지원하지 않는

    jungguji.github.io

     

Designed by Tistory.