본문 바로가기
Programming/Spring

[Spring Boot] Maven 프로젝트 Heroku 에 배포하기

by dinB 2022. 7. 1.

* 메모용입니다.

 

회사에서 로컬 환경에서 개발 중인 스프링 부트 프로젝트를 빠르게 배포하여 확인해보고 싶었다.

 

프론트 개발자 분도 현재까지 완성된 프로젝트를 Netlify 에 우선적으로 테스트를 위해 배포해놓은 상태였고,

스프링 부트도 배포하여 전체적인 프로젝트의 윤곽이 어떻게 보일지 확인해보고자 하였다.

 

초기에는 CI/CD 서버를 구축하여 한번에 전반적인 세팅까지 끝내볼까 했지만, 비용도 그렇고 시간도 넉넉치 않은 탓에 추후 일정으로 미뤄두고 빠르게 배포할 수 있는 방법을 찾게되었다.

 

본 포스팅은 다음과 같은 Step 에 대해 다룬다.

 

  1. 스프링 부트와 Maven 으로 구성된 매우 간단한 서버를 배포해본다.
  2. .properties 혹은 .yml 에서 사용되는 외부 환경 변수도 헤로쿠를 활용하여 주입해본다.
  3. 헤로쿠를 통해 배포된 어플리케이션의 로그를 CLI 를 통해 확인하는 방법을 살펴본다.

포스팅을 위해 작성한 매우 간단한 보잘 것 없는 코드지만, 본 포스팅에서 사용한 소스의 Git 은 여기서 확인할 수 있다.

 

GitHub - dinb1242/heroku-spring-boot-demo

Contribute to dinb1242/heroku-spring-boot-demo development by creating an account on GitHub.

github.com


1. Heroku (헤로쿠)

 

Cloud Application Platform | Heroku

Heroku is a platform as a service (PaaS) that enables developers to build, run, and operate applications entirely in the cloud.

www.heroku.com

Whether you're building a simple prototype or a business-critical product, Heroku's fully-managed platform gives you the simplest path to delivering apps quickly.

 

한 마디로 헤로쿠는 다양한 언어에 대하여 쉽고 빠르게 배포를 떠주는 클라우드 플랫폼인 Paas 이다.

Git 의 Repository 와 연동하여 프로젝트를 간편히 Deploy 할 수 있다.

 

기본적으로 헤로쿠는 Node.js, Ruby, Java, Python 등등 다양한 언어들을 지원한다고 한다.


2. 배포 환경

현재 배포하려고 하는 스프링 부트의 개발환경은 다음과 같다. (포스팅을 위해 매우 단순한 로직으로 구성됨.)

또한, 해당 프로젝트는 Git Repository 로 관리되고 있는 상태이다.

 

  • Spring Boot 2.7.1
  • Maven
  • Java 11

3. 프로젝트 구성

Demo 를 위해 매우 간단히 구성한 프로젝트이다. 해당 프로젝트는 Git Repository 를 통해 관리되고 있다.

 

.yml 파일에서는 server 의 port 를 Placeholder 로 배치하였다. 추후 헤로쿠에 배포 시, 헤로쿠가 외부에서 포트를 자동으로 주입해주기 때문이다. 그렇지 않으면 서버가 안 켜진다...

 

그 다음으로는 .yml 파일에서 외부 환경 변수로 주입된 Placeholder 인 "test.str" 를 "test-string" 에 저장하고, 이를 DemoController.java 에서 전달받아 간단한 GET 메소드에서 출력해볼 것이다.

 

또한, 이 GET 메소드는 추후 헤로쿠에서 배포된 이후, 동작 테스트를 위해 사용된다.

 

* application.yml

server:
  port: ${port:8080}

test-string: ${test.str}

 

* DemoController.java

@Slf4j
@RestController
@RequestMapping("/demo")
public class DemoController {

    @Value("${test-string}")
    private String testString;

    @GetMapping("")
    public ResponseEntity<String> getAnyValue() throws Exception {
        log.info(String.format("외부에서 삽입된 변수: %s", testString));
        return new ResponseEntity<>("이 텍스트가 나오면 정상 동작하는겁니다.", HttpStatus.OK);
    }

}

4. 헤로쿠 배포를 위한 사전 작업

4-1. system.properties

Java 환경에서 헤로쿠는 배포 시, 기본적으로 Java 8 버전을 기준으로 빌드를 한다고 한다.

 

따라서, 특별한 Config 파일을 하나 생성하여 추후 헤로쿠가 Java 11 버전으로 프로젝트를 빌드할 수 있도록 설정해주어야 한다. 

 

프로젝트의 최상단 루트 디렉토리에 "system.properties" 파일을 하나 생성한다.

 

 

그리고 해당 파일의 내부에 다음 커맨드를 작성한다.

 

java.runtime.version=11

 

자세한 정보는 더 찾아보아야 알겠지만, 아마 헤로쿠가 빌드할 때 해당 파일을 읽어들여서 빌드 시 참조하는 것 같다.

(공식 도큐먼트에서도 자세한 이야기는 안 나오는 것 같다. 단지 이 파일을 만들어서 빌드하기를 원하는 자바 버전을 명시하라는 문구만 존재했다.)

 

4-2. Procfile

profile 의 오타가 아니다. Procfile 이 맞다.

 

Procfile 이란, 헤로쿠가 프로젝트에 대한 빌드 이후 빌드된 서버가 실행될 때 작동할 커맨드들을 명시할 수 있는 파일이다.

 

system.properties 와 동일하게 프로젝트의 최상단에 Procfile 이라는 파일을 생성하면 된다.

 

 

해당 파일 안에 빌드 이후 헤로쿠가 어플리케이션을 실행할 수 있는 커맨드를 작성해주면 된다. 나의 경우, 매우 간단한 프로젝트이기 때문에 다음과 같은 커맨드를 명시해주었다.

 

web: java -jar target/demo-0.0.1-SNAPSHOT.war -Dserver.port=$PORT

 

상기 커맨드는 두 개의 파트로 나눌 수 있는데,

첫 번째 파트인 "web:" 은 헤로쿠의 process type 이라고 불리는 녀석이다.

 

web, worker, urgentworker, clock 등 다양한 타입이 존재하는데, 이 중 내가 사용하는 web 타입은 헤로쿠의 라우터를 통해 외부 HTTP 트래픽을 전달받을 수 있는 타입이라고 한다.

 

공식 도큐먼트에서는 배포하고자하는 앱이 웹 서버일 경우, web process type 을 사용해야한다고 설명하고 있다.

 

A Heroku app’s web process type is special: it’s the only process type that can receive external HTTP traffic from Heroku’s routers. If your app includes a web server, you should declare it as your app’s web process.

 

상기 커맨드의 두 번째 파트는 말 그대로 커맨드(Command) 라고 불린다.

빌드 이후 어플리케이션 실행 시 동작할 커맨드를 작성하면 된다.

 

나의 경우, 매우 단순히 "java -jar target/demo-0.0.1-SNAPSHOT.war -Dserver.port=$PORT" 를 작성해주었는데,

여기서 주의할 점은 빌드 이후 "demo-0.0.1-SNAPSHOT.war" 가 위치한 경로를 적어주어야 한다.

 

Maven 의 경우, 빌드 이후 target 디렉토리 안에 빌드 파일이 생성되기 때문에 루트 폴더 기준 해당 경로를 작성해주면 된다.

 

그리고  "-Dserver.port=$PORT" 프로퍼티를 명시함으로써 헤로쿠가 배포 이후 서버를 실행할 때 랜덤한 port 를 .yml 의 "server.port" 로 주입할 수 있다. 명시해주지 않으면 TIMEOUT 이 발생하며 서버가 안 켜진다!!!


5. 배포

이제 본격적으로 헤로쿠를 통해 배포를 시작한다. 회원가입 과정은 생략하고, 로그인 이후부터 진행한다.

 

로그인 이후, 화면의 우측 상단에 위치한 Dashboard 탭을 클릭한다.

 

나의 경우 이미 기존에 배포된 서버가 존재하므로 초기 사용자의 UI 와는 다르게 표현된다.

"Create new app" 을 클릭한다.

 

여기서 App name 을 지정해주는데, 추후 CLI 에서 프로젝트 로그를 확인하기 위한 식별자의 용도로 사용된다.

나는 hello-heroku-proj 라는 이름으로 지정해주었다.

 

이후, "Create App" 버튼을 클릭하여 생성을 완료한다. 

 

생성 이후, Git Repository 에 등록된 프로젝트를 불러와 배포할 것이므로, Deploy 탭에서 스크린샷 중간에 위치한 Deployment method 에서 GitHub 를 선택한 후 GitHub 에 로그인한다.

 

그리고 Connect to GitHub 란에서 배포하고자 하는 Repository 를 검색 후, "Connect" 버튼을 클릭한다.

 

Repository 를 선택하였다면, 하단의 두 개의 란이 나오는데, 각각 "Automatic deploys" 와 "Manual deploy" 이다.

 

Automatic deploys 의 경우, 선택한 Branch 를 감시하고 있다가, Push 가 감지되면 자동으로 재배포를 떠준다.

하지만 나의 경우, 그냥 Manual deploy 로 선택해서 수동으로 배포를 수행하는 방식을 선택했다.

 

빌드할 Branch 를 선택한 후, "Deploy Branch" 버튼을 클릭하면 빌드 및 배포가 진행된다. 

 

빌드가 완료되면 다음과 같은 화면이 나오고, 하단의 "View" 버튼을 클릭하면 배포된 어플리케이션을 확인할 수 있다.

 

악! 확인해보니 에러가 발생했다. 글을 작성하며 진행하니 오류가 이쁘게 나온다.

이래서 로그를 확인해봐야한다. 이제 상세 로그를 확인하는 방법을 찾아보자 ^^

 

6. 헤로쿠 로그 확인

로그를 확인하기 위해서는 헤로쿠 CLI 를 설치해야한다. 하단의 링크를 통해 설치하도록 한다.

 

 

The Heroku CLI | Heroku Dev Center

Last updated April 26, 2022 The Heroku Command Line Interface (CLI) lets you create and manage Heroku apps directly from the terminal. It’s an essential part of using Heroku. Install the Heroku CLI Pre-requisites The Heroku CLI requires Git, the popular

devcenter.heroku.com

링크의 중간 쯤으로 내리면 다음과 같이 설치할 수 있는 란이 나오는데, 해당하는 버전으로 다운 받아 설치한다.

 

설치가 완료되면, CLI 환경에서 헤로쿠에 로그인해야한다. 하기 커맨드를 입력한다.

 

heroku login

 

나오는대로 해주면 된다. 아무 키나 눌러서 로그인해준다.

 

매우 직관적이다. 로그인 버튼을 클릭하여 로그인을 완료한다!

 

이제 로그를 확인해보자. 하단의 커맨드를 실행한다.

 

heroku logs -a <헤로쿠 프로젝트명> --tail

# 나의 경우, 하단의 커맨드
heroku logs -a hello-heroku-proj --tail

 

--tail 명령어를 활용하면, 실시간 로그를 확인할 수 있다.

 

확인해보니, H10 코드에 "App crashed" 라고 오류가 출력됨을 확인할 수 있다. 그리고 상단 로그를 확인해보니, 스프링 부트가 실행되다가 말았음을 확인할 수 있다.

 

스크롤을 올려 중간쯤을 확인하니, 아차! 싶었다. 바로 .yml 에서 외부 환경 변수를 주입하고, 이를 DemoController.java 에서 호출하여 사용하는데, 해당 값이 주입되지 않고 있던 것이다.

 

이제 외부 환경 변수를 주입해야한다...

 

7. 헤로쿠 외부 환경 변수 주입

상단에서는 "test.str" 이라는 Placeholder 에 아무런 값을 넣지 않아 에러가 발생했다고 나온다. 그럼 헤로쿠에서 빌드 이후 서버 실행 시 외부에서 환경변수를 주입시켜주면 된다!

 

 

헤로쿠 프로젝트의 탭 중, "Settings" 를 클릭하고, 하단의 "Reveal Config Vars" 를 클릭한다. 해당 란에서 외부 환경 변수를 주입할 수 있다.

 

예시로, 기존 커맨드라인에서 jar 파일을 실행할 때에는, java -jar <Jar 파일명> --db.url=localhost --db.username=root ... 와 같이 외부에서 환경 변수를 yml 단에 주입할 수 있었는데, 그것과 동일하다.

 

 

.yml 파일에 정의한 대상 Placeholder 인 "test.str" 를 Key 로, 주입할 값을 Value 에 넣어주면 세팅은 끝난다.

 

다시 빌드하고 실행해본다.

 

 

당황하지 않는다. 고작 /demo 엔드포인트를 갖는 API 하나만 만들었기 때문이다. Postman 을 통해 /demo 엔드포인트로 GET 메소드를 호출해본다.

 

 

깔-끔