코드스테이츠 59일차
학습 목표
- Gradle 기반의 애플리케이션 실행 파일을 빌드 할 수 있다.
- 빌드로 생성된 애플리케이션 실행 파일을 로컬 PC에서 실행할 수 있다.
- 애플리케이션 빌드 시, 프로파일(Profile)을 적용할 수 있다.
- Spring Boot 기반 애플리케이션의 기본적인 배포 방법을 이해할 수 있다.
우리가 지금까지 만든 애플리케이션은 IntelliJ IDE 안에서만 실행 시켜보았다.
실제 외부의 클라이언트가 우리가 만든 애플리케이션의 API를 사용할 수 있으려면 애플리케이션의 빌드 과정을 거친 후에 생성되는 실행 파일을 서버에 배포해야 한다.
[기본] 애플리케이션 빌드/실행/배포
애플리케이션 빌드
우리는 지금까지 IntelliJ IDE의 도움을 받아 샘플 애플리케이션을 실행시켰다.
그런데 우리가 만든 애플리케이션을 로컬 환경이 아닌 서버 환경에서 실행 가능하게 하려면 Gradle이나 Maven 같은 빌드 툴을 이용해서 Spring Boot 기반의 애플리케이션 소스 코드를 빌드하는 기본적인 방법은 알고 있어야 한다.
✔ IntelliJ IDE를 이용한 빌드
- 우측 상단의 [Gradle] 윈도우 탭을 클릭한다.
- 프로젝트 이름 > Tasks > build에서 :bootJar 또는 :build task를 더블 클릭한다.
빌드가 정상적으로 종료되면 build/libs 디렉토리에 Jar 파일 하나가 생성된다.
생성된 Jar 파일은 우리의 로컬 PC에서 실행 가능한 애플리케이션 실행 파일이다.
:build와 :bootJar 중 어떤 task를 실행해서 애플리케이션 실행 파일을 만들어야 될까?
:build 태스크를 실행하면 :assemble, :check 같이 Gradle에서 빌드와 관련된 모든 task들을 실행시킨다. 그리고 실행 가능한 Jar 파일 이외에 plain Jar 파일 하나를 더 생성한다.
반면에 :bootJar는 빌드와 관련된 모든 task들을 실행하는 것이 아니라 애플리케이션의 실행 가능한 Jar(Executable Jar)파일을 생성하기 위한 task만 실행한다.
단순히 Executable Jar 파일만 필요하다면 :bootJar task를 실행하면 된다.
✔ Gradle Task를 이용한 빌드
IntelliJ IDE를 이용하면 클릭 몇 번 만으로 손쉽게 빌드할 수 있지만 때로는 IntelliJ IDE가 설치되어 있지 않은 상황에서 빌드를 해야될 경우도 생길 수 있을 것이다.
이럴땐 Gradle task 명령어를 콘솔에서 바로 입력하여 빌드를 진행할 수 있다.
맥의 경우는 터미널에 디렉토리 경로로 이동해준 후 ./gradlew build를 입력해주면 된다.
빌드가 정상적으로 종료되면 IntelliJ에서 빌드를 진행 할 때와 마찬가지로 build/libs 디렉토리에 Jar 파일 하나가 생성된다.
애플리케이션 실행
빌드가 성공적으로 완료되었다면 이제 생성된 Jar(Executable Jar) 파일을 이용해서 애플리케이션을 실행할 수 있다.
애플리케이션 실행 순서는?
- 빌드를 통해 생성된 Jar 파일이 있는 디렉토리 경로로 이동한다.
- 터미널 창에 java -jar Jar 파일명.jar를 입력한다. 그 결과로 우리가 만든 애플리케이션을 서버 환경에서 실행 시킬 수 있다.
✅ 프로파일(Profile) 적용
그런데 우리가 지금까지 만든 애플리케이션에는 한가지 문제점이 있는데 그것은 바로 데이터베이스이다.
우리는 현재 실습 중인 로컬 환경에서 인메모리 DB인 H2를 사용하고 있다.
그런데 빌드된 애플리케이션 실행 파일을 서버 환경에서 운영한다면 인메모리 DB를 사용하면 안된다.
어떤 이유로 인해 서버가 다운된다거나 그로 인해 애플리케이션이 한 번이라도 재시작해야 되는 경우가 생긴다면 인메모리 DB에 저장된 데이터는 모두 초기화 될테니까…
이를 해결하기 위해서는 로컬 환경에서 개발을 진행할 때는 기존 application.yml 파일에 이미 설정되어 있는 H2를 사용하고, 서버용 jar 파일을 빌드할 경우에는 빌드 전에 application.yml 파일에 기존의 H2 정보 대신에 서버에서 사용하는 DB 정보로 수정한 뒤에 빌드하면 될 것이다.
그러나 매번 그렇게 하는건 너무 불편하고 비효율적이며 개발자스럽지 못하다는 생각이 들 것이다.
이런 불편함을 줄이기 위해서 Spring에서는 프로파일(Profile)이라는 아주 편리한 기능을 제공한다.
우리가 만든 애플리케이션에 프로파일(Profile)을 적용해서 애플리케이션이 빌드 될 때, 로컬 환경에서는 로컬 환경의 DB 설정 정보를 실행 파일에 포함하고, 서버 환경일 경우에는 서버 환경의 DB 설정 정보를 실행 파일에 포함 하도록 해보자
먼저 application.yml 파일 외에 application-local.yml 파일과 application-server.yml 파일을 추가한다.
그리고 나서 세 개의 yml 파일의 내용을 각각 아래와 같이 구성하자
application.yml
# 일반적으로 애플리케이션 실행 환경에 상관없는 공통 정보들은 application.yml에 설정할 수 있습니다.
# 현재는 비어있는 상태입니다.
application.yml 파일은 주로 애플리케이션의 실행 환경에 상관없이 공통적으로 적용할 수 있는 프로퍼티를 설정할 수 있다.
현재는 샘플 애플리케이션에는 특별히 필요한 공통 정보가 없으므로 비워두자
application-local.yml
# 로컬 환경에서 사용하는 정보들은 application-local.yml 파일에 설정합니다.
spring:
h2:
console:
enabled: true
path: /h2
datasource:
url: jdbc:h2:mem:test
jpa:
hibernate:
ddl-auto: create # (1) 스키마 자동 생성
show-sql: true # (2) SQL 쿼리 출력
properties:
hibernate:
format_sql: true # (3) SQL pretty print
sql:
init:
data-locations: classpath*:db/h2/data.sql
logging:
level:
org:
springframework:
orm:
jpa: DEBUG
server:
servlet:
encoding:
force-response: true
기존에 application.yml 파일에 설정해둔 프로퍼티들을 모두 application-local.yml 파일로 옮겼다.
application-server.yml
# 서버 환경에서 사용하는 정보들은 application-server.yml 파일에 설정합니다.
# 현재는 비어있는 상태입니다.
서버 환경에서 필요한 정보들은 application-server.yml 파일에 설정할 수 있다.
우리가 만약 샘플 애플리케이션을 실제 서버나 AWS 같은 클라우드에서 실행 시켜야 한다면 application-server.yml 파일에 설정하면 된다.
애플리케이션이 실행이 되었다면 H2 웹 콘솔(http://localhost:8080/h2)에 접속해보면 접속이 되지 않을 것이다.
왜??
우리가 프로파일 기능을 이용하기 위해 두 개의 yml 파일을 더 추가한 후, 기존에 application.yml 파일에 있던 H2 웹 콘솔 설정까지 application-local.yml 파일로 옮겼다.
그런데 우리가 애플리케이션을 실행시킬 때, 아직 프로파일을 적용하지 않았다.
애플리케이션을 실행시키면, 프로파일을 적용하든 그렇지 않든 application.yml 파일에 설정된 정보는 항상 읽어오지만 현재 application.yml 파일에 H2 관련 설정들이 존재하지 않기 때문에 H2 웹 콘솔이 정상적으로 접속되지 않는 것이다.
H2 웹 콘솔에 정상적으로 접속하기 위해서는 로컬 환경의 프로파일을 적용하면 된다.
✔ IntelliJ IDE에서 프로파일 적용
위와같이 다이얼로그를 오픈 하기 위해 애플리케이션 실행 파일이 위치한 셀렉트 박스를 클릭한 후, [Edit Configurations]를 클릭한다.
또한 위와 같이 --spring.profiles.active=local 을 입력해서 활성화 할 프로파일을 ‘local’로 지정한다. 여기서 ‘local’은 application-local.yml 파일명에서의 ‘local’을 가르킨다.
이제 애플리케이션을 다시 실행하면 H2 웹 콘솔에 정상적으로 접속이 되는걸 확인할 수 있다.
아래와 같이 출력되는 로그를 통해 ‘local’ 프로파일이 활성화 된 것을 확인할 수 있다.
. ____ _ __ _ _
/\\ / ___'_ __ _ _(_)_ __ __ _ \ \ \ \
( ( )\___ | '_ | '_| | '_ \/ _` | \ \ \ \
\\/ ___)| |_)| | | | | || (_| | ) ) ) )
' |____| .__|_| |_|_| |_\__, | / / / /
=========|_|==============|___/=/_/_/_/
:: Spring Boot :: (v2.7.1)
[main] c.c.Section3Week4BuildApplication : Starting Section3Week4BuildApplication using Java 11.0.1 on hjs6877 with PID 2756
[main] c.c.Section3Week4BuildApplication : The following 1 profile is active: local
...
...
✔ 빌드된 실행 파일에 프로파일 적용
그런데 IntelliJ IDE 같은 개발 환경에서 테스트를 위해 프로파일을 변경해야 할 경우도 있지만 프로파일 기능은 빌드된 실행 파일을 어느 환경에서 실행할 지 여부를 결정할 때 주로 사용된다.
그럼 이제 빌드 된 실행 파일에 프로파일을 적용해서 실행해보자
/d/codestates/project/kdt/for-ese/section3-week4-build/build/libs (main)
$ java -jar section3-week4-build-0.0.1-SNAPSHOT.jar --spring.profiles.active=local
java -jar section3-week4-build-0.0.1-SNAPSHOT.jar에 IntelliJ IDE에서 Program arguments에 추가했던 것과 동일하게 --spring.profiles.active=local 설정을 추가해 주면 된다.
애플리케이션 배포
✅ 전통적인 배포 방법
Spring Boot 기반의 Executable Jar 파일을 서버에 배포하는 가장 일반적인 방법은 scp나 sftp 같은 표준 유닉스 툴을 이용해서 서버로 간단히 전송하는 것이다.
서버로 전송된 Jar 파일은 JVM이 설치된 환경이라면 어디서든 손쉽게 실행할 수 있다.
✅ 클라우드 서비스를 위한 배포 방법
Executable Jar 파일은 특히 클라우드 환경에 손쉽게 배포할 수 있다.
- PaaS(Platform as a Service)
- ㄴCloud Foundry, Heroku
대표적인 PaaS 제공 기업인 Cloud Foundry에서 제공하는 cf command line 툴을 사용하면 Executable Jar 파일을 손쉽게 배포할 수 있다.
cf command line 툴 사용 예
$ cf push acloudyspringtime -p target/app-0.0.1-SNAPSHOT.jar
- IaaS(Infrastructure as a Service)
- ㄴExecutable Jar는 AWS Elastic Beanstalk, AWS Container Registry, AWS Code Deploy 같은 서비스를 이용해서 손쉽게 배포가 가능하다.
- ㄴMicrosoft의 클라우드 서비스인 Azure 역시 Azure Spring Cloud, Azure App Service 에서 Spring Boot 기반의 Executable Jar 파일 배포 기능을 제공한다.
- ㄴGoogle Cloud 역시 Executable Jar 파일 배포를 위한 여러가지 옵션을 제공하고 있다.
- CI / CD 플랫폼을 사용한 배포
- ㄴ우리가 실무에서 Executable Jar 파일에 대한 배포 자동화를 이루고 싶다면 Github Actions나 Circle CI 같은 CI / CD 플랫폼을 이용해 AWS나 Azure 같은 클라우드 서비스에 Executable Jar 파일을 자동 배포하도록 구성할 수 있다.
총정리
- Spring Boot 기반 애플리케이션을 가장 손쉽게 빌드할 수 있는 방법은 IntelliJ 같은 IDE의 기능을 활용하는 것이다.
- IDE 등의 기능을 활용하기 어려운 상황에서는 Gradle 명령어를 사용해 손쉽게 빌드할 수 있다.
- Spring에서는 프로파일 기능을 이용해서 빌드 후 생성되는 애플리케이션 실행 파일에 대한 실행 환경을 손쉽게 지정할 수 있다.
- Spring Boot 기반의 Executable Jar 파일은 전통적인 서버, 클라우드 환경, 가상화 환경에 손쉽게 배포할 수 있다.