[ECR] Spring Boot + JSP ํ๋ก์ ํธ JIB๋ก ECR ์ ๋ก๋ํ๊ธฐ
๊ธฐ์กด ์์ ์ ๋ณดํต RESTful API ํํ๋ก ๊ตฌ์ฑ์ด ๋ ์๋น์ค๋ฅผ ์ฃผ๋ก jib๋ก ์ฌ๋ ธ์์ง๋ง, ๊ธฐ์กด MPA ์๋น์ค์ ๋์ผํ Spring Boot ํ๋ก์ ํธ๋ฅผ ECR์ ์ ๋ก๋ํด์ผํ ์ผ์ด ์๊ฒผ๋ค.
๊ธฐ์กด ํ๋ก์ ํธ์ ๊ฒฝ์ฐ, ๋ฐฑ๋จ ์์ฒญ๋ง ๋ฐ์์ ์ฒ๋ฆฌํ๋ฉด ๋๊ธฐ์ JARํ์ผ๋ก ๋ฌถ์ด Jib๋ฅผ ํตํด ECR์ ๋ฐฐํฌ๋๋ ํํ๋ฅผ ๊ฐ์ก์ผ๋ ์ด๋ฒ์๋ ์น ๋ฆฌ์์ค๊น์ง ํฌํจ๋ ์ ์ฒด ํ๋ก์ ํธ๋ฅผ ๋ฐฐํฌํ์ฌ ์ด์ํด์ผ ํ๋ ์ํฉ์ด์๋ค.
- JAR vs WAR
JAR : Java ํด๋์ค, ๋ฉํ๋ฐ์ดํฐ ๋ฑ์ผ๋ก ๊ตฌ์ฑ๋ ์๋ฐ ์ดํ๋ฆฌ์ผ์ด์ ์ ๊ตฌ๋ํ๊ธฐ ์ํ ํ์ผ
WAR : JAR ๊ตฌ์ฑ ํ์ผ์ ํฌํจํ์ฌ ์๋ธ๋ฆฟ์ด๋ JSP๋ฑ ์น ์ ํ๋ฆฌ์ผ์ด์ ์ ๋ฐฐํฌ ๋ฐ ํ ์คํธ ํ๊ธฐ ์ํ ํ์ผ๋ค๋ก ๊ตฌ์ฑ๋ ํ์ผ
์ฃผ์ ์ฐจ์ด์ ์, ํด๋น ํ์ผ๋ค์ ๊ตฌ์ฑํ๋ ๋ด์ฉ ์ธก๋ฉด์ ์กด์ฌํ๋ค๋ ๊ฒ. ์ด์ฐ๋๊ฑด ์ ํ๋ฆฌ์ผ์ด์ ์ ๋ง๋ค์ด ๋ฐฐํฌํ ์ ์๋ค๋ ์ ์์๋ ํฐ ๋งฅ๋ฝ์ ๊ฐ์ด ํ๋ค.
๋ฐ๋ผ์, ๋ณธ์ธ์ด ๋ง๋ ์น ์ ํ๋ฆฌ์ผ์ด์ ์ ์ด๋ค ๊ตฌ์ฑ์ผ๋ก ๋ฐฐํฌ๋ฅผ ํ ๊ฒ์ธ์ง๋ ์ ํ์ ๋ฌธ์ ๋ค.
์ฐธ๊ณ : https://pediaa.com/what-is-the-difference-between-jar-and-war-files/
What is the Difference Between JAR and WAR Files - Pediaa.Com
The main difference between JAR and WAR Files is that the JAR files are the files that have Java class files, associated metadata and resources aggregated into a single file to execute a Java application while, the WAR files are the files that contain Serv
pediaa.com
- Jib
๋์ปค ๋ฐ๋ชฌ ์์ด ๋น๋ ์ด๋ฏธ์ง๋ฅผ ๋น ๋ฅด๊ฒ ๊ตฌ์ฑํ์ฌ ์ํ๋ ๋ ํ์งํ ๋ฆฌ/๋ ์ง์คํธ๋ฆฌ๋ก Push๊ฐ ๊ฐ๋ฅํ ํด
GitHub - GoogleContainerTools/jib: ๐ Build container images for your Java applications.
๐ Build container images for your Java applications. - GitHub - GoogleContainerTools/jib: ๐ Build container images for your Java applications.
github.com
- Jib JAR / Jib WAR
Jib ๋ฅผ ํตํด ECR์ ํธ์ํ๊ธฐ๋ก ํ๊ณ , ์ด๋ฅผ ์ํด jib๋ฅผ ์ธํ ํ์๋ค.
๊ธฐ์กด์ ์์ฑํด๋์๋ jib ๋ฅผ ์ด๋์ ๋ ์ฐธ๊ณ ํ๊ณ JAR๋ฐฐํฌ์ WAR๋ฐฐํฌ ์ฐจ์ด์ ๋ฐ๋ผ ์ ์ ํ ์ต์ ์ ๋๋์ด ์ฌ์ฉํ๋ค.
์ฐธ๊ณ - maven ์ฌ์ฉ ์
GitHub - GoogleContainerTools/jib: ๐ Build container images for your Java applications.
๐ Build container images for your Java applications. - GitHub - GoogleContainerTools/jib: ๐ Build container images for your Java applications.
github.com
์ฐธ๊ณ - gradle ์ฌ์ฉ ์
GitHub - GoogleContainerTools/jib: ๐ Build container images for your Java applications.
๐ Build container images for your Java applications. - GitHub - GoogleContainerTools/jib: ๐ Build container images for your Java applications.
github.com
- JIB ๋ฐฐํฌ ์ฝ๋ ์์ฑ
์ฐ์ , AWS์ ๊ฐ๋ฐ/๋ฐ๋ชจ/์ด์ 3๊ฐ์ ํ๊ฒฝ์ผ๋ก ๋๋์ด์์ด ํ๋กํ์ผ ์ ์ฉ์ ํ์๊ณ ์ด๋ฏธ์ง ํ๊ทธ๋ฅผ ํ์ฌ ๋ ์ง๋ก ์ฃผ์ด ์ต์ํ์ ๊ตฌ๋ถ์ด ๊ฐ๋ฅํ ๋ก ํ์๋ค. AWS CI/CD์์๋ ๋ฐฐํฌ๋ ์ด๋ฏธ์ง์ ํฐ ๋ณ๊ฒฝ์ด ์์ผ๋ฉด ์๋ก ๋น๋ํ์ฌ ๋ฐฐํฌํ์ง ์๊ธฐ ๋๋ฌธ์ ์ต์ํ์ ๋ฒ์ ๊ตฌ๋ถ์ด ํ์ํ๋ค
* Spring Boot Jar ๋ฐฐํฌ
// command_line ์์ -Dname=Value ๋ก ๋์ด์ค๋๋ฐ -D ๋ System property ์๋ฏธ. ๋ฐ๋ผ์, System.getProperty ๋ก ๊ฐ์ ธ์จ๋ค.
// ํ๋ก์ ํธ ๋ค์ ์ค์
def project = "project_name"
// ํ๋ก์ ํธ ๋ฉ์ด์ ๋ฒ์ ๋ช
def major_version = "0.1"
// ํ์ฌ์๊ฐ
def getDate() {
new Date().format('yyyyMMddHHmm')
}
jib {
// profile, image_name ๋ณ์ ์ค์
def profile = System.getProperty('profile')
def image_name
// profile ์ ๋ฐ๋ฅธ image ์ค์
// dev : ๊ฐ๋ฐ์๋ฒ
// demo : ๋ฐ๋ชจ์๋ฒ
// live : ์ด์์๋ฒ
if ( profile == 'dev' ) {
// ๊ฐ๋ฐ ์ธํ
image_name = "{ecr url}/" + project
} else if ( profile == 'demo') {
// ๋ฐ๋ชจ ์ธํ
image_name = "{ecr url}/" + project
} else if ( profile == 'live') {
// ๋ผ์ด๋ธ ์ธํ
image_name = "{ecr url}/" + project
} else {
// exception
}
from {
image = "adoptopenjdk/openjdk8:alpine-jre"
}
to {
image = image_name
tags = [major_version +'.' + getDate()]
}
container {
// Set JVM options.
jvmFlags = ['-Dspring.profiles.active=' + profile, '-XX:+UseContainerSupport', '-Dserver.port=8080', '-Dfile.encoding=UTF-8']
// Expose different port.
ports = ['8080']
}
println "#########################################################"
println "profile : " + profile
println "image name : " + image_name
println "tag : " + major_version + "." + getDate()
println "#########################################################"
}
* ์ Jar ์ฝ๋ ๊ธฐ๋ฐ WAR jib ๋ฐฐํฌ ์ฝ๋
// ํ๋ก์ ํธ ๋ค์ ์ค์
def project = "project_name"
// ํ๋ก์ ํธ ๋ฉ์ด์ ๋ฒ์ ๋ช
def major_version = "0.1"
// ํ์ฌ์๊ฐ
def getDate() {
new Date().format('yyyyMMddHHmm')
}
jib {
// profile, image_name ๋ณ์ ์ค์
def profile = System.getProperty('profile') == null ? "dev" : System.getProperty('profile')
def image_name
// profile ์ ๋ฐ๋ฅธ image ์ค์
// dev : ๊ฐ๋ฐ์๋ฒ
// demo : ๋ฐ๋ชจ์๋ฒ
// live : ์ด์์๋ฒ
if ( profile == 'dev' ) {
// ๊ฐ๋ฐ ์ธํ
image_name = "{ecr url}/" + project
} else if ( profile == 'demo') {
// ๋ฐ๋ชจ ์ธํ
image_name = "{ecr url}/" + project
} else if ( profile == 'live') {
// ๋ผ์ด๋ธ ์ธํ
image_name = "{ecr url}/" + project
} else {
// exception
}
// ๋น๋ ํ์ผ ์ถ๊ฐ ์ต์
extraDirectories.paths = "build/libs"
from {
image = "adoptopenjdk/openjdk8:alpine-jre"
}
to {
image = image_name
tags = [major_version +'.' + getDate()]
}
container {
// Set JVM options.
if ( profile == 'dev' ) {
entrypoint = ['java','-Dspring.profiles.active=' + profile, '-XX:+UseContainerSupport', '-Dserver.port=8080', '-Dfile.encoding=UTF-8', '-Xms512m', '-Xmx1024m', '-jar','/acaas-admin.war','']
} else if ( profile == 'demo') {
entrypoint = ['java','-Dspring.profiles.active=' + profile, '-XX:+UseContainerSupport', '-Dserver.port=8080', '-Dfile.encoding=UTF-8', '-Xms512m', '-Xmx1024m', '-jar','/acaas-admin.war','']
} else if ( profile == 'live') {
entrypoint = ['java','-Dspring.profiles.active=' + profile, '-XX:+UseContainerSupport', '-Dserver.port=8080', '-Dfile.encoding=UTF-8', '-jar','/acaas-admin.war','']
} else { }
// Expose different port.
ports = ['8080']
}
println "#########################################################"
println "profile : " + profile
println "image name : " + image_name
println "tag : " + major_version + "." + getDate()
println "#########################################################"
}
Jib Github ์๋ ์ธ๊ธ๋ ๋ด์ฉ์ธ๋ฐ ๊ธฐ๋ณธ์ ๋ก JIB๋ JAR ํ์์ ๋ฐฐํฌ๊ฐ ๊ธฐ๋ณธ์ด๊ณ WAR ํ๋ก์ ํธ์ ๋ํด์๋ ์กฐ๊ธ ๋ค๋ฅธ ์ต์ ๋์ ํด์ฃผ์ด์ผ ํ๋ค.
Jib also containerizes WAR projects. If the Gradle project uses the WAR Plugin, Jib will by default use jetty as a base image to deploy the project WAR. No extra configuration is necessary other than using the WAR Plugin to make Jib build WAR images.
Note that Jib will work slightly differently for WAR projects from JAR projects:
- container.mainClass and container.jvmFlags are ignored.
- The WAR will be exploded into /var/lib/jetty/webapps/ROOT, which is the expected WAR location for the Jetty base image.
To use a different Servlet engine base image, you can customize container.appRoot, container.entrypoint, and container.args. If you do not set entrypoint or args, Jib will inherit the ENTRYPOINT and CMD of the base image, so in many cases, you may not need to configure them. However, you will most likely have to set container.appRoot to a proper location depending on the base image. Here is an example of using a Tomcat image:
https://github.com/GoogleContainerTools/jib/blob/master/jib-gradle-plugin/README.md#war-projects
GitHub - GoogleContainerTools/jib: ๐ Build container images for your Java applications.
๐ Build container images for your Java applications. - GitHub - GoogleContainerTools/jib: ๐ Build container images for your Java applications.
github.com
์ ์ค๋ช ์ ๋ณด๋ฉด, WAR ํ๋ก์ ํธ ๋ฐฐํฌ์์๋ container.mainClass, container.jvmFlags ์ต์ ์ ๋ฌด์๋๋ฉฐ, ๊ธฐ๋ณธ ์น ์ฑ ๊ฒฝ๋ก๊ฐ fix ๋๋ค. ๊ทธ๋ฆฌ๊ณ Entrypoint ๋ cmd ์ต์ ์ด ์ ์๋์ง ์๋๋ค๋ฉด ์ด ๋ํ ์ ์ฉ๋์ง ์๋๋ค.
๋ฐ๋ผ์ WAR ๋ฐฐํฌ์์๋ ๋ฒ ์ด์ค ์ด๋ฏธ์ง๋ฅผ JDK๋ก ์ก์ ๊ฒ์ด๋ผ๋ฉด, Dockerfile๋ก ์ ํ๋ฆฌ์ผ์ด์ ์ ๊ธฐ๋ณธ ๋ฐฐํฌํ๋ ๊ฒ ์ฒ๋ผ
1. WAR ํ์ผ์ ๋ฒ ์ด์ค ์ด๋ฏธ์ง์ ํฌํจ์ํค๊ณ
2. ํด๋น ํ์ผ์ java -jar๋ฅผ ํตํด ์คํ์ํค๋
๋ฐฉ๋ฒ์ ์ทจํด์ผ ํ๋ค. ์ JIB ์ฝ๋๋ฅผ ๋ณด๋ฉด ํด๋น ๋ด์ฉ๋ค ๋ํ ์ถ๊ฐ๊ฐ ๋์ด์๋ ๊ฒ์ ๋ณผ ์ ์๋ค.
๋ณดํต ๊ฒ์ํด๋ณด๋ฉด, WAR ํ๋ก์ ํธ์ ๊ฒฝ์ฐ ๋ฆฌ์์ค ํฌ๊ธฐ๊ฐ ํฌ๊ณ , ์ด๋ฅผ ์๋ฒ์ ์ฌ๋ ธ์ ๊ฒฝ์ฐ์๋ CPU ์ด์ฉ๋ฅ ์ด ๋์์ง๋ ๋ฑ์ ๋ฌธ์ ๊ฐ ์์ผ๋ JAR ํ์์ ์ฌ์ฉํ๋ผ๊ณ ๊ถ๊ณ ํ๊ณ ์๋ค. ํ์ง๋ง WAR ๋ํ ์ ํ๋ฆฌ์ผ์ด์ ์ ๋ฐฐํฌํ๋ ๋ฐฉ๋ฒ ์ค์ ํ๋์ด๊ณ ๊ธฐ์กด์ ๋ฐฐํฌ ํด์์ ์ง์ํ์ง ์๋ ๊ฒ๋ ์๋๋ค.
๋ค๋ง, ํ์ฌ ์ด์ํ๊ณ ์ ํ๋ ํ๊ฒฝ์ ์์ด WAR ํ๋ก์ ํธ์ ๋ฆฌ์์ค ํฌ๊ธฐ๋ ์ฌ์ฉ๋ฅ ์ ๋ฌธ์ ๊ฐ ์๋ค๋ฉด ํด๋น ๋ฐฉ์์ผ๋ก ๋ฐฐํฌํ๋ ๊ฒ๋ ๊ฒฐ์ฝ ๋์์ง ์์ ์ ํ์ด๋ผ๊ณ ํ ์ ์๋ค๊ณ ๋ณธ๋ค.