-
Notifications
You must be signed in to change notification settings - Fork 0
/
building-spring-boot-docker-images.html
71 lines (69 loc) · 22 KB
/
building-spring-boot-docker-images.html
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
<!DOCTYPE html><html lang="de-ch"><head><meta charset="utf-8"><meta http-equiv="X-UA-Compatible" content="IE=edge"><meta name="viewport" content="width=device-width,initial-scale=1"><title>Building Spring Boot Docker Images - Finecloud</title><meta name="description" content="Pre-Requirements Developer Environment ready with Docker, JDK, IDE A Java Spring Boot Project with a h2 in-memory DB Docker Hub account Create Docker File Create a Dockerfile with the following content: FROM openjdk:11-jre-slim ENV JAVA_OPTS ' -Xms512m -Xmx512m -Djava.security.egd=file:///dev/./urandom' WORKDIR application COPY target/myapp-0.0.1-SNAPSHOT.jar ./ ENTRYPOINT…"><meta name="generator" content="Publii Open-Source CMS for Static Site"><link rel="stylesheet" href="https://www.finecloud.ch/media/plugins/syntaxHighlighter/prism-black.css"><link rel="canonical" href="https://www.finecloud.ch/building-spring-boot-docker-images.html"><link rel="alternate" type="application/atom+xml" href="https://www.finecloud.ch/feed.xml"><link rel="alternate" type="application/json" href="https://www.finecloud.ch/feed.json"><meta property="og:title" content="Building Spring Boot Docker Images"><meta property="og:site_name" content="Finecloud"><meta property="og:description" content="Pre-Requirements Developer Environment ready with Docker, JDK, IDE A Java Spring Boot Project with a h2 in-memory DB Docker Hub account Create Docker File Create a Dockerfile with the following content: FROM openjdk:11-jre-slim ENV JAVA_OPTS ' -Xms512m -Xmx512m -Djava.security.egd=file:///dev/./urandom' WORKDIR application COPY target/myapp-0.0.1-SNAPSHOT.jar ./ ENTRYPOINT…"><meta property="og:url" content="https://www.finecloud.ch/building-spring-boot-docker-images.html"><meta property="og:type" content="article"><link rel="shortcut icon" href="https://www.finecloud.ch/media/website/finecloud.png" type="image/png"><link rel="stylesheet" href="https://www.finecloud.ch/assets/css/style.css?v=39da73365516a098a9b73b721fc970e2"><script type="application/ld+json">{"@context":"http://schema.org","@type":"Article","mainEntityOfPage":{"@type":"WebPage","@id":"https://www.finecloud.ch/building-spring-boot-docker-images.html"},"headline":"Building Spring Boot Docker Images","datePublished":"2023-05-02T21:45","dateModified":"2023-05-03T20:34","description":"Pre-Requirements Developer Environment ready with Docker, JDK, IDE A Java Spring Boot Project with a h2 in-memory DB Docker Hub account Create Docker File Create a Dockerfile with the following content: FROM openjdk:11-jre-slim ENV JAVA_OPTS ' -Xms512m -Xmx512m -Djava.security.egd=file:///dev/./urandom' WORKDIR application COPY target/myapp-0.0.1-SNAPSHOT.jar ./ ENTRYPOINT…","author":{"@type":"Person","name":"Finecloud","url":"https://www.finecloud.ch/authors/finecloud/"},"publisher":{"@type":"Organization","name":"Finecloud"}}</script><meta name="google-site-verification" content="seFY9U12uiEq5U3_MyZiX6XWzk0AVFl9zITr2ZKsytY"></head><body><div class="site-container"><header class="top" id="js-header"><a class="logo" href="https://www.finecloud.ch/">Finecloud</a><nav class="navbar js-navbar"><button class="navbar__toggle js-toggle" aria-label="Menu" aria-haspopup="true" aria-expanded="false"><span class="navbar__toggle-box"><span class="navbar__toggle-inner">Menu</span></span></button><ul class="navbar__menu"><li><a href="https://www.finecloud.ch/" target="_self">Blog</a></li><li><a href="https://www.finecloud.ch/tags/" target="_self">Tags</a></li></ul></nav><div class="search"><div class="search__overlay js-search-overlay"><div class="search__overlay-inner"><form action="https://www.finecloud.ch/search.html" class="search__form"><input class="search__input js-search-input" type="search" name="q" placeholder="search..." aria-label="search..." autofocus="autofocus"></form><button class="search__close js-search-close" aria-label="Close">Close</button></div></div><button class="search__btn js-search-btn" aria-label="Search"><svg role="presentation" focusable="false"><use xlink:href="https://www.finecloud.ch/assets/svg/svg-map.svg#search"/></svg></button></div></header><main><article class="post"><div class="hero"><figure class="hero__image hero__image--overlay"><img src="https://www.finecloud.ch/media/website/download.jpg" srcset="https://www.finecloud.ch/media/website/responsive/download-xs.jpg 300w, https://www.finecloud.ch/media/website/responsive/download-sm.jpg 480w, https://www.finecloud.ch/media/website/responsive/download-md.jpg 768w, https://www.finecloud.ch/media/website/responsive/download-lg.jpg 1024w, https://www.finecloud.ch/media/website/responsive/download-xl.jpg 1360w, https://www.finecloud.ch/media/website/responsive/download-2xl.jpg 1600w" sizes="100vw" loading="eager" alt=""></figure><header class="hero__content"><div class="wrapper"><div class="post__meta"><time datetime="2023-05-02T21:45">Mai 2, 2023</time></div><h1>Building Spring Boot Docker Images</h1></div></header></div><div class="wrapper post__entry"><div class="post__toc"><h3>Table of Contents</h3><ul><li><a href="#mcetoc_1gvhe7lit17h">Pre-Requirements</a></li><li><a href="#mcetoc_1gvhe7lit17i">Create Docker File</a></li><li><a href="#mcetoc_1gvhe7lit17j">Build and Run the Docker Image</a></li><li><a href="#mcetoc_1gvhe7lit17k">Add Layer Tool in Maven</a></li><li><a href="#mcetoc_1gvhe7lit17l">Enable Multi-Stage Dockerfile</a></li><li><a href="#mcetoc_1gvhe7lit17m">Build the Docker Image with Maven</a></li><li><a href="#mcetoc_1gvhe7lit17n">Push your Docker Image to Docker Hub</a></li></ul></div><h2 id="mcetoc_1gvhe7lit17h">Pre-Requirements</h2><ul><li>Developer Environment ready with Docker, JDK, IDE</li><li>A Java Spring Boot Project with a h2 in-memory DB</li><li>Docker Hub account</li></ul><h2 id="mcetoc_1gvhe7lit17i">Create Docker File</h2><p>Create a Dockerfile with the following content:</p><pre class="hljs" style="color: #a9b7c6; background: #282b2e; display: block; overflow-x: auto; padding: 0.5em;"><span class="hljs-keyword" style="color: #cc7832;">FROM</span> openjdk:<span class="hljs-number" style="color: #6897bb;">11</span>-jre-slim
<span class="hljs-keyword" style="color: #cc7832;">ENV</span> JAVA_OPTS <span class="hljs-string" style="color: #6a8759;">" -Xms512m -Xmx512m -Djava.security.egd=file:///dev/./urandom"</span>
WORKDIR application
<span class="hljs-keyword" style="color: #cc7832;">COPY</span> <span class="bash">target/myapp-0.0.1-SNAPSHOT.jar ./
</span><span class="hljs-keyword" style="color: #cc7832;">ENTRYPOINT</span> <span class="bash">[<span class="hljs-string" style="color: #6a8759;">"java"</span>, <span class="hljs-string" style="color: #6a8759;">"-jar"</span>, <span class="hljs-string" style="color: #6a8759;">"myapp-0.0.1-SNAPSHOT.jar"</span>]</span></pre><div>make sure the Paths where the .jar files are stored matches with your environment.</div><h2 id="mcetoc_1gvhe7lit17j">Build and Run the Docker Image</h2><p>Build the image with this command:</p><p><code><span class="blob-code-inner blob-code-marker js-code-nav-pass" data-code-marker="+"><span class="pl-c1">docker build -f ./src/main/Dockerfile -t myapp .</span></span></code></p><p>Run the image with this command:</p><p><code><span class="blob-code-inner blob-code-marker js-code-nav-pass" data-code-marker="+"><span class="pl-c1">docker run -p 8080:8080 -d myapp</span></span></code></p><p>The Spring Application-Context should now be loaded and started inside the Container. You can verify this with the <code>docker ps -a</code> and <code>docker logs -f <containername></code> commands.</p><h2 id="mcetoc_1gvhe7lit17k">Add Layer Tool in Maven</h2><p>Make sure that you have enabled the Layer Tool with having this content in the pom.xml file:</p><pre class="hljs" style="color: #a9b7c6; background: #282b2e; display: block; overflow-x: auto; padding: 0.5em;"> <span class="hljs-tag"><<span class="hljs-name" style="color: #e8bf6a;">plugin</span>></span>
<span class="hljs-tag"><<span class="hljs-name" style="color: #e8bf6a;">groupId</span>></span>org.springframework.boot<span class="hljs-tag"></<span class="hljs-name" style="color: #e8bf6a;">groupId</span>></span>
<span class="hljs-tag"><<span class="hljs-name" style="color: #e8bf6a;">artifactId</span>></span>spring-boot-maven-plugin<span class="hljs-tag"></<span class="hljs-name" style="color: #e8bf6a;">artifactId</span>></span>
<span class="hljs-tag"><<span class="hljs-name" style="color: #e8bf6a;">configuration</span>></span>
<span class="hljs-tag"><<span class="hljs-name" style="color: #e8bf6a;">layers</span>></span>
<span class="hljs-tag"><<span class="hljs-name" style="color: #e8bf6a;">enabled</span>></span>true<span class="hljs-tag"></<span class="hljs-name" style="color: #e8bf6a;">enabled</span>></span>
<span class="hljs-tag"><<span class="hljs-name" style="color: #e8bf6a;">includeLayerTools</span>></span>true<span class="hljs-tag"></<span class="hljs-name" style="color: #e8bf6a;">includeLayerTools</span>></span>
<span class="hljs-tag"></<span class="hljs-name" style="color: #e8bf6a;">layers</span>></span>
<span class="hljs-tag"><<span class="hljs-name" style="color: #e8bf6a;">excludes</span>></span>
<span class="hljs-tag"><<span class="hljs-name" style="color: #e8bf6a;">exclude</span>></span>
<span class="hljs-tag"><<span class="hljs-name" style="color: #e8bf6a;">groupId</span>></span>org.projectlombok<span class="hljs-tag"></<span class="hljs-name" style="color: #e8bf6a;">groupId</span>></span>
<span class="hljs-tag"><<span class="hljs-name" style="color: #e8bf6a;">artifactId</span>></span>lombok<span class="hljs-tag"></<span class="hljs-name" style="color: #e8bf6a;">artifactId</span>></span>
<span class="hljs-tag"></<span class="hljs-name" style="color: #e8bf6a;">exclude</span>></span>
<span class="hljs-tag"></<span class="hljs-name" style="color: #e8bf6a;">excludes</span>></span>
<span class="hljs-tag"></<span class="hljs-name" style="color: #e8bf6a;">configuration</span>></span>
<span class="hljs-tag"></<span class="hljs-name" style="color: #e8bf6a;">plugin</span>></span></pre><div class="flex flex-grow flex-col gap-3"><div class="min-h-[20px] flex flex-col items-start gap-4 whitespace-pre-wrap break-words"><div class="markdown prose w-full break-words dark:prose-invert light"><p>Enabling the layer tool in a Java Spring project that runs in a Docker container can help reduce the size of the Docker image, which can be especially important in a production environment. The layer tool feature allows the Spring Boot application to be broken down into layers, where each layer contains a subset of the application's dependencies and resources. This makes it possible to separate the application's core functionality from its dependencies, such as external libraries and resources.</p><p>By separating the application's dependencies into separate layers, Docker can cache each layer independently, making it easier to reuse existing layers when building new Docker images. This can significantly reduce the amount of time it takes to build and deploy new versions of the application.</p><p>Enabling the layer tool also allows you to take advantage of other features, such as layer analysis, which can help you optimize your Docker image even further by identifying potential areas for improvement.</p><p>In summary, enabling the layer tool in a Java Spring project that runs in a Docker container can help reduce the size of the Docker image, improve the speed of deployment, and optimize resource usage.</p><h2 id="mcetoc_1gvhe7lit17l">Enable Multi-Stage Dockerfile</h2><p>Now we want to create a example of a Multi-Stage Dockerfile, like so:</p><pre class="hljs" style="color: #a9b7c6; background: #282b2e; display: block; overflow-x: auto; padding: 0.5em;"><span class="hljs-keyword" style="color: #cc7832;">FROM</span> openjdk:<span class="hljs-number" style="color: #6897bb;">11</span>-jre-slim as builder
<span class="hljs-keyword" style="color: #cc7832;">WORKDIR</span> <span class="bash">application
</span><span class="hljs-keyword" style="color: #cc7832;">ADD</span> <span class="bash">target/myapp-0.0.1-SNAPSHOT.jar ./
</span><span class="hljs-keyword" style="color: #cc7832;">RUN</span> <span class="bash">java -Djarmode=layertools -jar myapp-0.0.1-SNAPSHOT.jar extract
</span>
<span class="hljs-keyword" style="color: #cc7832;">FROM</span> openjdk:<span class="hljs-number" style="color: #6897bb;">11</span>-jre-slim
<span class="hljs-keyword" style="color: #cc7832;">WORKDIR</span> <span class="bash">application
</span><span class="hljs-keyword" style="color: #cc7832;">COPY</span> <span class="bash">--from=builder application/dependencies/ ./
</span><span class="hljs-keyword" style="color: #cc7832;">COPY</span> <span class="bash">--from=builder application/spring-boot-loader/ ./
</span><span class="hljs-keyword" style="color: #cc7832;">COPY</span> <span class="bash">--from=builder application/snapshot-dependencies/ ./
</span><span class="hljs-keyword" style="color: #cc7832;">COPY</span> <span class="bash">--from=builder application/application/ ./
</span><span class="hljs-keyword" style="color: #cc7832;">ENTRYPOINT</span> <span class="bash">[<span class="hljs-string" style="color: #6a8759;">"java"</span>, <span class="hljs-string" style="color: #6a8759;">"-Djava.security.egd=file:///dev/./urandom"</span>, <span class="hljs-string" style="color: #6a8759;">"org.springframework.boot.loader.JarLauncher"</span>]</span></pre><p>now we can recreate the image like so: <code><span class="blob-code-inner blob-code-marker js-code-nav-pass" data-code-marker="+"><span class="pl-c1">docker build -f ./src/main/docker/Dockerfile -t myapp .</span></span></code></p><h2 id="mcetoc_1gvhe7lit17m">Build the Docker Image with Maven</h2><p>So far it's very uncomfortable to have the Version of the .jar Artifact in the Dockerfile. This way we would need to change this after every new release. There is a better way: we can use the Docker Maven plugin. Add this dependency to your pom.xml:</p><pre class="hljs" style="color: #a9b7c6; background: #282b2e; display: block; overflow-x: auto; padding: 0.5em;"><span class="hljs-tag"><<span class="hljs-name" style="color: #e8bf6a;">plugin</span>></span>
<span class="hljs-tag"><<span class="hljs-name" style="color: #e8bf6a;">groupId</span>></span>io.fabric8<span class="hljs-tag"></<span class="hljs-name" style="color: #e8bf6a;">groupId</span>></span>
<span class="hljs-tag"><<span class="hljs-name" style="color: #e8bf6a;">artifactId</span>></span>docker-maven-plugin<span class="hljs-tag"></<span class="hljs-name" style="color: #e8bf6a;">artifactId</span>></span>
<span class="hljs-tag"><<span class="hljs-name" style="color: #e8bf6a;">version</span>>0.42.1</span><span class="hljs-tag"></<span class="hljs-name" style="color: #e8bf6a;">version</span>></span>
<span class="hljs-tag"><<span class="hljs-name" style="color: #e8bf6a;">configuration</span>></span>
<span class="hljs-tag"><<span class="hljs-name" style="color: #e8bf6a;">verbose</span>></span>true<span class="hljs-tag"></<span class="hljs-name" style="color: #e8bf6a;">verbose</span>></span>
<span class="hljs-tag"><<span class="hljs-name" style="color: #e8bf6a;">images</span>></span>
<span class="hljs-tag"><<span class="hljs-name" style="color: #e8bf6a;">image</span>></span>
<span class="hljs-tag"><<span class="hljs-name" style="color: #e8bf6a;">name</span>></span>yourdockeraccount/myapp<span class="hljs-tag"></<span class="hljs-name" style="color: #e8bf6a;">name</span>></span>
<span class="hljs-tag"><<span class="hljs-name" style="color: #e8bf6a;">build</span>></span>
<span class="hljs-tag"><<span class="hljs-name" style="color: #e8bf6a;">assembly</span>></span>
<span class="hljs-tag"><<span class="hljs-name" style="color: #e8bf6a;">descriptorRef</span>></span>artifact<span class="hljs-tag"></<span class="hljs-name" style="color: #e8bf6a;">descriptorRef</span>></span>
<span class="hljs-tag"></<span class="hljs-name" style="color: #e8bf6a;">assembly</span>></span>
<span class="hljs-tag"><<span class="hljs-name" style="color: #e8bf6a;">dockerFile</span>></span>Dockerfile<span class="hljs-tag"></<span class="hljs-name" style="color: #e8bf6a;">dockerFile</span>></span>
<span class="hljs-tag"><<span class="hljs-name" style="color: #e8bf6a;">tags</span>></span>
<span class="hljs-tag"><<span class="hljs-name" style="color: #e8bf6a;">tag</span>></span>latest<span class="hljs-tag"></<span class="hljs-name" style="color: #e8bf6a;">tag</span>></span>
<span class="hljs-tag"><<span class="hljs-name" style="color: #e8bf6a;">tag</span>></span>${project.version}<span class="hljs-tag"></<span class="hljs-name" style="color: #e8bf6a;">tag</span>></span>
<span class="hljs-tag"></<span class="hljs-name" style="color: #e8bf6a;">tags</span>></span>
<span class="hljs-tag"></<span class="hljs-name" style="color: #e8bf6a;">build</span>></span>
<span class="hljs-tag"></<span class="hljs-name" style="color: #e8bf6a;">image</span>></span>
<span class="hljs-tag"></<span class="hljs-name" style="color: #e8bf6a;">images</span>></span>
<span class="hljs-tag"></<span class="hljs-name" style="color: #e8bf6a;">configuration</span>></span>
<span class="hljs-tag"></<span class="hljs-name" style="color: #e8bf6a;">plugin</span>></span></pre><p>make sure you add your image name!</p><p>Also you need to replace the Artifact Name of "<span class="bash">myapp-0.0.1-SNAPSHOT.jar</span>" with </p><div>"${project.build.finalName}.jar" in the Dockerfile.</div><div> </div><div>Now you can build the docker image with the maven plugin using a dynamic version.</div><h2 id="mcetoc_1gvhe7lit17n">Push your Docker Image to Docker Hub</h2><p>Last step is to push your Application to the docker hub. But first lets build the image with:</p><p><code>mvn clean package docker:build docker:push</code></p><p> </p></div></div></div></div><footer class="wrapper post__footer"><p class="post__last-updated">This article was updated on Mai 3, 2023</p><ul class="post__tag"><li><a href="https://www.finecloud.ch/tags/container/">container</a></li><li><a href="https://www.finecloud.ch/tags/docker/">docker</a></li><li><a href="https://www.finecloud.ch/tags/java/">java</a></li><li><a href="https://www.finecloud.ch/tags/softwareentwicklung/">software development</a></li><li><a href="https://www.finecloud.ch/tags/spring/">spring</a></li><li><a href="https://www.finecloud.ch/tags/spring-framework/">spring-framework</a></li></ul><div class="post__share"></div></footer></article><nav class="post__nav"><div class="post__nav-inner"><div class="post__nav-prev"><svg width="1.041em" height="0.416em" aria-hidden="true"><use xlink:href="https://www.finecloud.ch/assets/svg/svg-map.svg#arrow-prev"/></svg> <a href="https://www.finecloud.ch/data-validation-overview.html" class="post__nav-link" rel="prev"><span>Previous</span> Data Validation Overview</a></div><div class="post__nav-next"><a href="https://www.finecloud.ch/spring-boot-on-kubernetes.html" class="post__nav-link" rel="next"><span>Next</span> Spring Boot on Kubernetes </a><svg width="1.041em" height="0.416em" aria-hidden="true"><use xlink:href="https://www.finecloud.ch/assets/svg/svg-map.svg#arrow-next"/></svg></div></div></nav><div class="post__related related"><div class="wrapper"><h2 class="h5 related__title">You should also read:</h2><article class="related__item"><div class="feed__meta"><time datetime="2023-05-03T20:46" class="feed__date">Mai 3, 2023</time></div><h3 class="h1"><a href="https://www.finecloud.ch/spring-boot-on-kubernetes.html">Spring Boot on Kubernetes</a></h3></article><article class="related__item"><div class="feed__meta"><time datetime="2023-04-10T08:36" class="feed__date">April 10, 2023</time></div><h3 class="h1"><a href="https://www.finecloud.ch/spring-exception-handling.html">Spring Exception Handling</a></h3></article><article class="related__item"><div class="feed__meta"><time datetime="2023-04-04T15:29" class="feed__date">April 4, 2023</time></div><h3 class="h1"><a href="https://www.finecloud.ch/spring-bean-lifecycle.html">Spring Bean Lifecycle</a></h3></article></div></div></main><footer class="footer"><div class="footer__copyright"><p>Powered by Publii</p></div><button onclick="backToTopFunction()" id="backToTop" class="footer__bttop" aria-label="Back to top" title="Back to top"><svg><use xlink:href="https://www.finecloud.ch/assets/svg/svg-map.svg#toparrow"/></svg></button></footer></div><script>window.publiiThemeMenuConfig = {
mobileMenuMode: 'sidebar',
animationSpeed: 300,
submenuWidth: 'auto',
doubleClickTime: 500,
mobileMenuExpandableSubmenus: true,
relatedContainerForOverlayMenuSelector: '.top',
};</script><script defer="defer" src="https://www.finecloud.ch/assets/js/scripts.min.js?v=6ca8b60e6534a3888de1205e82df8528"></script><script>var images = document.querySelectorAll('img[loading]');
for (var i = 0; i < images.length; i++) {
if (images[i].complete) {
images[i].classList.add('is-loaded');
} else {
images[i].addEventListener('load', function () {
this.classList.add('is-loaded');
}, false);
}
}</script><script defer="defer" src="https://www.finecloud.ch/media/plugins/syntaxHighlighter/prism.js"></script></body></html>