Spring Example: ToDo List #9 배포

함형주·2022년 10월 10일
0

Spring Example: ToDo

목록 보기
10/16

질문, 피드백 등 모든 댓글 환영합니다.

Heroku를 이용하여 프로젝트를 배포하겠습니다. Heroku는 배포가 쉬운 편이며 서버와 db를 일정 범위 내에서 무료로 제공합니다. 단순한 프로젝트를 제작하며 공부하는 우리들에겐 괜찮은 선택일 수 있습니다. 대신 속도가 느립니다...
(수정 : Heroku는 free dyno 서비스를 2022년 11월 28일부로 종료했습니다. 대신 저비용 서비스인 eco dyno를 출시했습니다. 프로젝트 배포 과정은 거의 비슷하며 차이점과 eco dyno를 등록하고 free dyno에서 전환하는 내용은 블로그 참고해 주세요.)

블로그1, 블로그2, 블로그3, 블로그4, 블로그5, 블로그6을 참고하여 작성하였습니다.

heroku에서 jar 배포하기

jar를 배포하기 전에 추가 설정이 필요합니다.

system.properties

프로젝트 root에 system.properties 생성해줍니다. heroku의 자바는 기본 8버전으로 설정되어 있으므로 11로 지정해주어야 합니다.
java.runtime.version=11 추가해줍니다.

Procfile

프로젝트 root에 확장자 없이 Procfile을 생성합니다. (Profile이 아니라 Procfile입니다!)
Procfile에서 jar의 위치를 지정해주겠습니다.(원래 위치는 gitignore로 처리되어 있음)
web: java -Dserver.port=$PORT $JAVA_OPTS -jar target/todo-0.0.1-SNAPSHOT.jar

build.gradle

jar의 생성 위치를 변경해 줍니다. 맨 아래에 추가해주겠습니다.

bootJar {
	destinationDirectory = file("./target")
}

git.ignore

heroku에서 gradle/wrapper을 참조해야 하므로 gitignore에서 제외시켜줍니다.

jar 파일 생성

터미널에서 ./gradlew bootjar입력하여 jar파일 생성

H2 -> MySQL

h2는 heroku에서 사용할 수 없으므로 heroku 에서 지원하는 db인 MySQL로 바꿔주겠습니다.

build.gradle에서 H2 -> MySQL로 바꿔줍니다.

dependencies {
	runtimeOnly 'mysql:mysql-connector-java'
//	runtimeOnly 'com.h2database:h2'
}

이제 heroku 사이트에서 MySQL을 연동해주어야 합니다. (회원가입과 app 추가, 깃 연동 등 heroku 설정은 생략하겠습니다. 위 블로그를 참조해주세요.)

Resources -> find more add-ons -> JawsDB MySQL

연동 과정은 간단하니 생략하겠습니다. 위 블로그 참고해 주세요. 연동이 완료되면 Resources에서 JawsDB MySQL을 클릭하여 DB연동 정보를 확인합니다.

이를 기반으로 application.yml을 수정해주겠습니다.

application.yml

spring:
  datasource:
    url: jdbc:mysql://username:password@host......
    username: username
    password: password
    driver-class-name: com.mysql.cj.jdbc.Driver
    
  jpa:
    hibernate:
      ddl-auto: none

적절하게 db 정보를 추가해줍니다. (url 앞에 jdbc:를 추가해주세요)
ddl을 none으로 설정 뒤 MySQL에서 직접 테이블을 생성해줍니다.

jar 생성

이제 모든 사전 작업이 끝났으니 터미널에 ./gradlew bootjar를 입력해 jar를 생성해줍니다.

그리고 heroku에 연결할 git repository에 모든 변경사항을 push 합니다.

주의사항

우리가 작성한 application.yml에 db 접속 정보가 그대로 노출돼있기 때문에 public이 아닌 private 리포지토리에 업로드 해주셔야 합니다. (사실 private 리포지토리가 연동 되는 줄 모르고 application.yml 파일을 깃에 암호화에서 업로드하는 방법을 몇 시간 동안 찾아본....)

배포

heroku에서 git을 연동하고 Deploy -> Manual deploy에서 deploy를 해주면 배포가 완료 됩니다.

Thymeleaf 경로 문제 발생

배포 후 해당 url로 접속하니 첫 화면은 잘 나와서 배포가 잘 된 줄 알았으나...
/login 으로 접속하니 500 error 가 발생했습니다.. heroku 로그를 살펴보니 아래와 같았습니다.

2022-10-11 16:37:24.627 ERROR 4 --- [io-17757-exec-7] o.a.c.c.C.[.[.[/].[dispatcherServlet] : Servlet.service() for servlet [dispatcherServlet] in context with path [] threw exception [Request processing failed; nested exception is org.thymeleaf.exceptions.TemplateInputException: Error resolving template [/login/form], template might not exist or might not be accessible by any of the configured Template Resolvers] with root cause

로컬에서는 문제가 없었지만 배포 시에 문제가 발생했습니다.
설마 Thymeleaf를 사용하려면 heroku에서 추가로 설정이 필요한가 생각이 들어 관련 부분을 검색했고 블로그에서 답을 찾았습니다.

정리하자면 스프링(타임리프)의 디폴트 경로가 templates/ 이므로 컨트롤러에서 "/login/form" 을 반환하면 templates//login/form" 경로로 연결되므로 오류가 발생하고 로컬에서는 이를 IntelliJ가 잡아서 오류가 발생하지 않았던 것입니다.

때문에 모든 컨트롤러의 반환값을 수정하고 다시 배포하니 정상적으로 동작하였습니다.

다음으로..

블로그로 작성하니 배포에 큰 힘을 들이지 않은 것 같지만 실은 좌충우돌 그 자체였습니다...
사실 배포까지 하는 건 계획에 없던 일이지만 이왕 프로젝트 시작한 김에 끝까지 해보자는 생각이 들었습니다. 조잡하지만 배포까지 끝내고 나니 뿌듯함이 느껴졌습니다.
다음 시간엔 마지막으로 프로젝트를 되돌아 보며 마무리짓도록 하겠습니다.


github , 배포 URL (첫 접속 시 로딩이 걸릴 수 있습니다.)

profile
평범한 대학생의 공부 일기?

0개의 댓글