인프라/클라우드

Heroku SpringBoot 배포 체크리스트

jwKim96 2022. 3. 15. 15:23

1. Java 버전

  • 내가 Java8 이 아닌, 다른 버전을 쓰고있는지?
  • build.gradle 의 sourceCompatibility = '1.8' 인지?

heroku 관련 아무런 설정을 해주지 않으면, heroku 배포과정의 빌드 단계에서 java8 jdk 를 기본으로 사용합니다.
저는 java11 버전을 사용해서, 빌드 과정에서 오류가 발생했습니다.

해결

프로젝트 루트 경로에 system.properties 파일 생성

java.runtime.version=11

(참고 : https://devcenter.heroku.com/articles/java-support#supported-java-versions)

이 설정파일을 추가해주면, heroku 가 java11 jdk 를 사용해서 정상적으로 빌드 됩니다.

2. *-plain.jar 생성 방지

배포 빌드 과정에서 다음과 같은 메세지를 볼 수 있습니다.

no main manifest attribute, in~~

아무런 설정을 해주지 않으면, 빌드할때 두가지 jar 파일이 생성됩니다.

  1. 프로젝트이름-0.0.1-SNAPSHOT-plain.jar
  2. 프로젝트이름-0.0.1-SNAPSHOT.jar

여기서 OO-plain.jar 는 의존성이 포함되지않은, 제가 작성한 코드만으로 구성되어있습니다.
그리고 이 plain.jar 는 main method 위치를 알려줘야 합니다.
하지만 메인 메소드 위치를 알려주더라도 프로젝트 실행에 필요한 의존성이 포함되어있지않기 때문에 단독으로는 실행이 안됩니다.

그래서 저희는 프로젝트 실행을 위해서 모든 의존성이 포함된(Tomcat 포함) 2번 jar만 있으면 됩니다.

문제는 이건 빌드 후 실행 과정에 발생하는 오류인데, heroku 빌드는 성공으로 인식됩니다.
그래서 문제를 찾기가 어려웠습니다.

그런데 두 파일이 있는데도 실행이 실패하는 이유는 아래와 같습니다.

heroku 가 빌드 후 SpringBoot 어플리케이션을 실행해줄 때, 아래 명령어를 기본으로 실행합니다.
java -Dserver.port=$PORT $JAVA_OPTS -jar build/libs/*.jar
(참고 : https://devcenter.heroku.com/articles/deploying-gradle-apps-on-heroku#default-web-process-type)

즉, 두 jar를 함께 실행하기 때문인데요.
이를 해결하는 방법은 두 가지 입니다.

해결방법 1 (plain.jar 생성 방지)

plain jar 가 생성되는것을 방지하려면 build.gradle 에 아래 설정을 추가해주면 됩니다.

jar {
    enabled = false
}

해결방법 2 (특정 jar 만 실행되도록)

heroku 에서 빌드가 끝나고 실행 단계에서 실행될 명령을 미리 정의할 수 있습니다.

프로젝트에 Procfile 이라는 이름의 파일을 생성해 줍니다.(확장자 없음)
그리고 아래 내용을 입력하면 됩니다.

java -jar ./build/libs/프로젝트이름-0.0.1-SNAPSHOT.jar

이렇게 하면 plain.jar 가 있어도, 정상적으로 실행이됩니다.
(참고 : https://devcenter.heroku.com/articles/deploying-gradle-apps-on-heroku#the-procfile)

[선택] 3. Timezone 설정

저는 프로젝트 내부에서 LocalDateTime 을 사용했는데요.
heroku 는 기본적으로 timezone 이 UTC 로 설정되어있어서 한국시간과 다르게 나옵니다.

이를 한국 시간으로 변경하는 방법은 간단합니다.

Settings-Config Vars에서 Reveal Config Vars 를 클릭하면 아래 사진처럼 환경변수를 추가할 수 있습니다.
아래 그림처럼 두번째 줄에 설정을 추가하고 저장해주시면 됩니다.