[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๊ฐ€ ๊ฐ€๋Šฅํ•œ ํˆด

    https://github.com/GoogleContainerTools/jib/blob/master/jib-gradle-plugin/README.md#extradirectories-object

     

    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 ์‚ฌ์šฉ ์‹œ

    https://github.com/GoogleContainerTools/jib/blob/master/jib-maven-plugin/README.md#extradirectories-object

     

    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 ์‚ฌ์šฉ ์‹œ

    https://github.com/GoogleContainerTools/jib/blob/master/jib-maven-plugin/README.md#extradirectories-object

     

    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 ํ”„๋กœ์ ํŠธ์˜ ๋ฆฌ์†Œ์Šค ํฌ๊ธฐ๋‚˜ ์‚ฌ์šฉ๋ฅ ์— ๋ฌธ์ œ๊ฐ€ ์—†๋‹ค๋ฉด ํ•ด๋‹น ๋ฐฉ์‹์œผ๋กœ ๋ฐฐํฌํ•˜๋Š” ๊ฒƒ๋„ ๊ฒฐ์ฝ” ๋‚˜์˜์ง€ ์•Š์€ ์„ ํƒ์ด๋ผ๊ณ  ํ•  ์ˆ˜ ์žˆ๋‹ค๊ณ  ๋ณธ๋‹ค. 

     

    728x90
    ๋ฐ˜์‘ํ˜•

    ๋Œ“๊ธ€