1<!DOCTYPE HTML> 2<html lang="en"> 3<head> 4 <meta charset="utf-8" /> 5 <meta name="viewport" content="width=device-width, initial-scale=1" /> 6 <meta property="og:site_name" content="Masterspringboot" /> 7 <meta property="og:type" content="article" /> 8 <meta name="author" content="Francesco Marchioni" /> 9 <title>Running Spring Boot applications as a Service - Masterspringboot</title> 10<meta name="description" content="Running Spring Boot applications as a Service is pretty simple and this tutorial will show how to do it in just 5 minutes. In order to install your Spring"> 11<meta name="path" content="/configuration/various-configuration/running-spring-boot-applications-as-a-service/" /> 12<meta name="category" content="Core & Quickstarts" /> 13<meta name="keywords" content="Spring Boot, Service, Maven, Gradle, LinuxInitD" /> 14<meta name="updated" content="11-9-2026" /> 15 16 17 <!-- Ezoic: consent + loader â il più in alto possibile nell'head, prima di qualsiasi 18 altro script, così il consenso GDPR/CMP si stabilisce prima che qualsiasi altro tag 19 pubblicitario/di tracciamento provi a caricarsi. data-cfasync="false" su tutti e 4: 20 evita che Cloudflare Rocket Loader li riscriva/differisca a modo suo. --> 21
21<script data-cfasync="false" src="https://cmp.gatekeeperconsent.com/min.js"></script>
21 22
22<script data-cfasync="false" src="https://the.gatekeeperconsent.com/cmp.min.js"></script>
22 23
23<script data-cfasync="false" async src="//www.ezojs.com/ezoic/sa.min.js"></script>
23 24
24<script data-cfasync="false"> 25 window.ezstandalone = window.ezstandalone || {}; 26 ezstandalone.cmd = ezstandalone.cmd || []; 27 </script>
27 28 29 <!-- 1. Preconnect & DNS Prefetch per domini critici e terze parti --> 30 <link rel="preconnect" href="https://fonts.googleapis.com"> 31 <link rel="preconnect" href="https://fonts.gstatic.com" crossorigin> 32 <link rel="preconnect" href="https://www.googletagmanager.com"> 33 <link rel="dns-prefetch" href="https://www.googletagmanager.com"> 34 <link rel="preconnect" href="https://cdnjs.cloudflare.com" crossorigin> 35 <link rel="dns-prefetch" href="https://cdnjs.cloudflare.com"> 36 <link rel="icon" type="image/svg+xml" href="/favicon.svg"> 37 38 <!-- 2. Google Fonts Asincrono (Non Bloccante) --> 39 <link rel="preload" href="https://fonts.googleapis.com/css2?family=Open+Sans:ital,wght@0,400;0,600;1,400;1,600&family=Roboto+Slab:wght@400;700&display=swap" as="style" onload="this.onload=null;this.rel='stylesheet'"> 40 <noscript><link rel="stylesheet" href="https://fonts.googleapis.com/css2?family=Open+Sans:ital,wght@0,400;0,600;1,400;1,600&family=Roboto+Slab:wght@400;700&display=swap"></noscript> 41 42 <!-- 3. FontAwesome Asincrono (Non Bloccante) --> 43 <link rel="preload" href="/assets/css/fontawesome-all.min.css" as="style" onload="this.onload=null;this.rel='stylesheet'"> 44 <noscript><link rel="stylesheet" href="/assets/css/fontawesome-all.min.css"></noscript> 45 46 <!-- 4. CSS Principale di Layout --> 47 <link rel="stylesheet" href="/assets/css/main.css" /> 48 <link rel="icon" type="image/svg+xml" href="/favicon.svg"> 49 <!-- Fix Flexbox Overflow per il codice sorgente + spazio riservato per gli ads (riduce il CLS) --> 50 <style> 51 #main { min-width: 0 !important; } 52 pre { max-width: 100% !important; overflow-x: auto !important; white-space: pre !important; } 53 code { white-space: pre !important; } 54 .ad-slot { display: block; min-height: 90px; margin: 1.5em 0; } 55 </style> 56 57 <!-- Prism CSS Asincrono --> 58 <link rel="preload" href="https://cdnjs.cloudflare.com/ajax/libs/prism/1.29.0/themes/prism-tomorrow.min.css" as="style" onload="this.onload=null;this.rel='stylesheet'"> 59 <noscript><link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/prism/1.29.0/themes/prism-tomorrow.min.css"></noscript> 60 61 <!-- ANALYTICS: caricato dopo il load della pagina --> 62
62<script> 63 window.dataLayer = window.dataLayer || []; 64 function gtag(){ dataLayer.push(arguments); } 65 function mtbLoadAnalytics(){ 66 if (window.__mtbGaLoaded) return; 67 window.__mtbGaLoaded = true; 68 var s = document.createElement('script'); 69 s.async = true; 70 s.src = 'https://www.googletagmanager.com/gtag/js?id=G-WF6YFFG84C'; 71 document.head.appendChild(s); 72 gtag('js', new Date()); 73 gtag('config', 'G-WF6YFFG84C'); 74 } 75 if (document.readyState === 'complete') { 76 mtbLoadAnalytics(); 77 } else { 78 window.addEventListener('load', mtbLoadAnalytics); 79 } 80 </script>
80 81 <!-- END ANALYTICS--> 82 83 84</head> 85 86<body class="is-preload"> 87 88 <!-- Wrapper --> 89 <div id="wrapper"> 90 91 <!-- Main --> 92 <div id="main"> 93 <div class="inner"> 94 95 <!-- Header del Sito --> 96 <header id="header"> 97 <a href="/index.html" class="logo"><strong>Masterspringboot</strong></a> 98 </header> 99 100 <section> 101 <!-- MTB-ARTICLE-TOP (lazy-loaded via IntersectionObserver, vedi script a fine pagina) --> 102 <div class="ad-slot"> 103 <ins class="adsbygoogle" 104 style="display:block" 105 data-ad-client="ca-pub-3643784008511888" 106 data-ad-slot="4992715025" 107 data-ad-format="auto" 108 data-full-width-responsive="true"></ins> 109 </div> 110 <header class="main"> 111 <h1>Running Spring Boot applications as a Service</h1> 112</header> 113<div> 114 <div itemprop="text"> 115 <div class="tldr-box"> 116 <p><strong></strong> Running Spring Boot 3.x applications as persistent background services is best handled using modern <code>systemd</code> unit files for Linux virtual machines, GraalVM AOT native compilation for ultra-fast startup times, or Cloud Native Buildpacks (<code>./mvnw spring-boot:build-image</code>) for containerized deployments. Legacy SysV <code>init.d</code> symlinks have been superseded by <code>systemd</code> standards and container runtimes.</p> 117 </div> 118 <p>Running <strong>Spring Boot applications as a Service</strong> ensures high availability, process management, auto-restart capability on failures, and standard operating system integration. While early versions of Spring Boot relied on SysV <code>init.d</code> symlinks, Spring Boot 3.x applications deployed on modern Linux environments leverage <code>systemd</code> service units, native GraalVM binaries, or OCI container images.</p> 119 <p><span id="more-90"></span></p> 120 <h2>1. Fully Executable Application JARs & systemd Services</h2> 121 <p>To run your Spring Boot 3.x application as a system service on modern Linux distributions (such as Ubuntu, RHEL, or Debian), first configure your build tool to package an executable archive. In Maven, add the <code><executable></code> configuration to the <code>spring-boot-maven-plugin</code>:</p><!-- Body: empty descriptor, Ezoic picks the size --> 122
122<script> 123 ezstandalone.cmd.push(function () { 124 ezstandalone.showAds({}); 125 }); 126</script>
126 127 <pre><code class="language-markup"><project xmlns="http://maven.apache.org/POM/4.0.0" 128 xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 129 xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> 130 <modelVersion>4.0.0</modelVersion> 131 132 <build> 133 <plugins> 134 <plugin> 135 <groupId>org.springframework.boot</groupId> 136 <artifactId>spring-boot-maven-plugin</artifactId> 137 <configuration> 138 <executable>true</executable> 139 </configuration> 140 </plugin> 141 </plugins> 142 </build> 143</project></code></pre> 144 <p>Similarly, in Gradle, enable launch script generation inside your <code>build.gradle</code>:</p> 145 <pre><code class="language-groovy">tasks.named('bootJar') { 146 launchScript() 147}</code></pre> 148 <p>Package your production archive using the Maven wrapper:</p> 149 <pre><code class="language-bash">$ ./mvnw clean package -DskipTests=true</code></pre> 150 <p>Rather than symlinking to obsolete <code>/etc/init.d</code> scripts, modern Linux deployments standardize on <code>systemd</code>. Create a service unit definition file at <code>/etc/systemd/system/demoapp.service</code>:</p> 151 <pre><code class="language-ini">[Unit] 152Description=Demo Spring Boot Service 153After=syslog.target network.target 154 155[Service] 156User=springapp 157Group=springapp 158Type=simple 159ExecStart=/usr/bin/java -jar /opt/demoapp/demoapp.jar 160SuccessExitStatus=143 161Restart=always 162RestartSec=10 163Environment="SPRING_PROFILES_ACTIVE=prod" 164 165[Install] 166WantedBy=multi-user.target</code></pre> 167 <p>Enable and start the service using standard system control commands:</p><!-- Body: empty descriptor, Ezoic picks the size --> 168
168<script> 169 ezstandalone.cmd.push(function () { 170 ezstandalone.showAds({}); 171 }); 172</script>
172 173 <pre><code class="language-bash">$ sudo systemctl daemon-reload 174$ sudo systemctl enable demoapp 175$ sudo systemctl start demoapp 176$ sudo systemctl status demoapp</code></pre> 177 <h2>2. Containerized Services via Cloud Native Buildpacks</h2> 178 <p>In modern cloud environments, running applications as containerized services is standard practice. Spring Boot 3.x includes built-in support for Cloud Native Buildpacks, allowing you to generate OCI-compliant container images directly without maintaining a custom <code>Dockerfile</code>.</p> 179 <p>Execute the image build goal with Maven or Gradle:</p> 180 <pre><code class="language-bash"># Maven Buildpack creation 181$ ./mvnw spring-boot:build-image 182 183# Gradle Buildpack creation 184$ ./gradlew bootBuildImage</code></pre> 185 <p>The resulting image includes a production-ready JRE, optimized layer caching, and enterprise security defaults ready for Docker or Kubernetes deployment.</p><!-- Body: empty descriptor, Ezoic picks the size --> 186
186<script> 187 ezstandalone.cmd.push(function () { 188 ezstandalone.showAds({}); 189 }); 190</script>
190 191 <h2>3. High-Performance Services with GraalVM Native Images</h2> 192 <p>Spring Boot 3.x features built-in Ahead-Of-Time (AOT) compilation support via GraalVM. Compiling your application into a native binary delivers instant startup times and significantly reduced memory usage, perfect for system services and microservices.</p> 193 <p>Compile a native binary using the built-in Spring Boot Maven or Gradle plugins:</p> 194 <pre><code class="language-bash"># Maven Native Compile 195$ ./mvnw -Pnative native:compile 196 197# Gradle Native Compile 198$ ./gradlew nativeCompile</code></pre> 199 <p>The compiled standalone binary in the <code>target/</code> directory requires no Java runtime (JRE) installed on the destination server. You can execute it directly within a lightweight <code>systemd</code> unit file:</p> 200 <pre><code class="language-ini">[Unit] 201Description=GraalVM Native Spring Boot Service 202After=network.target 203 204[Service] 205User=springapp 206ExecStart=/opt/demoapp/demoapp 207Restart=always 208 209[Install] 210WantedBy=multi-user.target</code></pre> 211 <h2>4. Externalized Configuration for Spring Boot 3.x Services</h2> 212 <p>When binding custom configuration settings for your service, modern Spring Boot 3.x leverages Java 17/21 Records alongside <code>jakarta.validation</code> annotations. Note that explicit <code>@ConstructorBinding</code> is no longer required on single-constructor records.</p><!-- Body: empty descriptor, Ezoic picks the size --> 213
213<script> 214 ezstandalone.cmd.push(function () { 215 ezstandalone.showAds({}); 216 }); 217</script>
217 218 <pre><code class="language-java">package com.example.demo.config; 219 220import jakarta.validation.constraints.Max; 221import jakarta.validation.constraints.Min; 222import jakarta.validation.constraints.NotBlank; 223import org.springframework.boot.context.properties.ConfigurationProperties; 224import org.springframework.validation.annotation.Validated; 225 226@Validated 227@ConfigurationProperties(prefix = "app.service") 228public record ServiceConfigProperties( 229 @NotBlank String name, 230 @Min(1000) @Max(65535) int port, 231 boolean autoStart 232) {}</code></pre> 233 <p>To import externalized YAML configuration files into your service environment without obsolete annotation hacks, use the modern <code>spring.config.import</code> key in your <code>application.yml</code>:</p> 234 <pre><code class="language-yaml">spring: 235 config: 236 import: 237 - "optional:file:/etc/demoapp/config/service-override.yml" 238 main: 239 banner-mode: "off" 240 241app: 242 service: 243 name: "Production Microservice" 244 port: 8080 245 auto-start: true</code></pre> 246 <h2>Frequently Asked Questions (FAQs)</h2> 247 <h3>Why should I use systemd service files instead of legacy /etc/init.d symlinks?</h3> 248 <p>Modern Linux distributions have standardized on <code>systemd</code>. Unlike legacy SysV <code>init.d</code> scripts, <code>systemd</code> provides process supervision, automatic restarts upon crash, resource limits (CPU and RAM restrictions), centralized journal logging via <code>journalctl</code>, and proper dependency sequencing during operating system boot.</p> 249 <h3>Is a JRE required on the host server when deploying GraalVM native services?</h3> 250 <p>No. GraalVM Ahead-Of-Time (AOT) compilation packages your compiled Java code, framework metadata, and necessary SubstrateVM runtime components into a single platform-native binary executable. It runs natively on the target operating system without needing a Java Development Kit (JDK) or JRE installed.</p> 251 <h3>How do I import external YAML configuration files into a Spring Boot 3.x service?</h3> 252 <p>Spring Boot 3.x replaces legacy <code>@PropertySource</code> YAML workarounds with the standard <code>spring.config.import</code> property in <code>application.properties</code> or <code>application.yml</code> (e.g., <code>spring.config.import=optional:file:/etc/demoapp/config.yml</code>).</p> 253 </div> 254</div> 255 256<!-- BEGIN RECOMMENDED ARTICLES --> 257<hr class="major" /> 258<section> 259Recommended Articles</h2> 260<div class="row"> 261 <div class="col-6 col-12-small"> 262 <div class="box"> 263 <a href="/getting-started-with-spring-boot/spring-boot-3-0-a-simple-example/">Spring Boot 3: A simple tutorial with example - Masterspringboot</a></h3> 264 <p>Spring Boot is a popular Java-based framework used to build web and stand-alone applications. It is built on top of the Spring framework and makes it easy</p> 265 </div> 266 </div> 267 <div class="col-6 col-12-small"> 268 <div class="box"> 269 <a href="/configuration/various-configuration/how-to-send-mails-in-spring-boot-applications/">How to send mails in Spring Boot Applications - Masterspringboot</a></h3> 270 <p>The Spring Framework provides a straightforward abstraction for sending email by using the JavaMailSender interface, and Spring Boot provides</p> 271 </div> 272 </div> 273 <div class="col-6 col-12-small"> 274 <div class="box"> 275 <a href="/programming/various/monitoring-the-performance-of-spring-method-execution/">Monitoring the performance of Spring method execution - Masterspringboot</a></h3> 276 <p>This tutorial discusses how to monitor the performance of Spring applications with regards to method execution, using AspectJ open source framework.</p> 277 </div> 278 </div> 279 <div class="col-6 col-12-small"> 280 <div class="box"> 281 <a href="/programming/various/spring-boot-eh-cache/">Spring Boot Cache example - Masterspringboot</a></h3> 282 <p>This tutorial covers all basic aspects of using a Cache implementation named Ehcache in Spring Boot. We will start with some basic cache definitions and</p> 283 </div> 284 </div> 285</div> 286</section> 287<!-- END RECOMMENDED ARTICLES --> 288 289 <!-- ARTICLE_FOOTER --> 290 </section> 291 292 </div> 293 </div> 294 295 <!-- Sidebar --> 296 <div id="sidebar"> 297 <div class="inner"> 298 <nav id="menu"> 299 <!-- 300 <header class="major"> 301 <h2>Quick Links</h2> 302 </header> 303 <ul> 304 <li><a href="/top-articles.html">ð¥ Top Articles</a></li> 305 <li><a href="/cheatsheets.html">ð Cheatsheets</a></li> 306 <li><a href="/faq.html">â FAQ Hub</a></li> 307 </ul> 308--> <!-- In the sidebar --> 309
309<script> 310 ezstandalone.cmd.push(function () { 311 ezstandalone.showAds({sizes: "300x600"}); 312 }); 313 </script>
313 314 <header class="major"> 315 <h2>Categories</h2> 316 </header> 317 <ul> 318 <li><a href="/all-articles.html">All articles</a></li> 319 <li><a href="/categories/data-access.html">Data Access</a></li> 320 <li><a href="/categories/integration.html">Integration</a></li> 321 <li><a href="/categories/core-and-quickstarts.html">Core and Quickstarts</a></li> 322 <li><a href="/categories/cloud.html">Cloud</a></li> 323 <li><a href="/categories/containers.html">Containers</a></li> 324 <li><a href="/categories/security.html">Security</a></li> 325 <li><a href="/categories/observability.html">Observability</a></li> 326 <li><a href="/categories/testing.html">Testing</a></li> 327 <li><a href="http://www.mastertheboss.com" target="_blank">JBoss / WildFly</a></li> 328 </ul> 329</nav><!-- Footer --> 330<footer id="footer"> 331 <p class="copyright">© Masterspringboot. Design: HTML5 UP.</p> 332</footer> 333 </div> 334 </div> 335 336 </div> <!-- Fine Wrapper --> 337 338 <!-- Scripts con attributo DEFER per scaricare in parallelo senza bloccare il render --> 339
339<script defer src="/assets/js/jquery.min.js"></script>
339 340
340<script defer src="/assets/js/browser.min.js"></script>
340 341
341<script defer src="/assets/js/breakpoints.min.js"></script>
341 342
342<script defer src="/assets/js/util.js"></script>
342 343
343<script defer src="/assets/js/main.js"></script>
343 344 345
345<script defer src="https://cdnjs.cloudflare.com/ajax/libs/prism/1.29.0/prism.min.js"></script>
345 346
346<script defer src="https://cdnjs.cloudflare.com/ajax/libs/prism/1.29.0/components/prism-markup.min.js"></script>
346 347
347<script defer src="https://cdnjs.cloudflare.com/ajax/libs/prism/1.29.0/components/prism-bash.min.js"></script>
347 348
348<script defer src="https://cdnjs.cloudflare.com/ajax/libs/prism/1.29.0/components/prism-java.min.js"></script>
348 349
350<script type="module" src="https://static.cloudflareinsights.com/beacon.min.js/v31edd6df95cf4e85bb4c19e7a9bdbcba1788362987495" integrity="sha512-iIg7k2xntmwu6/uSb5tpc/hySgZc4eoL31yB29W6tJFo2akwjPWcEqnCEdJvGexCL0KEQwVYv5BlowfhVz26hg==" data-cf-beacon='{"version":"2024.11.0","token":"480e591761fa44acb358a0a7ff4bd775","r":1,"spa":2}' crossorigin="anonymous"></script>
350 351</body> 352</html>
Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.