Spring Boot as a Linux service
Introduction
In this post, I'll show you how to configure a Spring Boot application to run as a service on Linux.
First, I'll show you how to configure the service with scripts compatible with System V init systems. Then, I'll explain how to configure the service on newer systems that use systemd.
Executable Jar
One of the advantages of Spring Boot is that it allows us to create self-contained executable Jars, which lets us treat the packaged application in a Jar directly as an executable that provides parameters like "start", "stop", "restart", "status" that are useful when managing services.
To create an executable Jar, we need to do one of the following two configurations depending on whether we use Maven or Gradle:
Maven
Add the following to the project's pom.xml:
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
<configuration>
<executable>true</executable>
</configuration>
</plugin>
Gradle
Add the following to the project's build.gradle
:
springBoot {
executable = true
}
Starting the application from the Jar, in addition to supporting the previously mentioned options, implies the following:
- The script starts the application with the user who owns the script
- The script tracks the application's PID using
/var/run/<applicationname>/<applicationname>.pid
- The script writes logs to
/var/log/<applicationname>.log
Installation as init.d service (System V)
For this case, we'll leverage the previously mentioned properties of executable Jars that can be created in Spring Boot.
In this case, the task will be as simple as adding a symbolic link to the Jar in the init.d
directory:
sudo ln -s /var/<applicationpath>/<applicationname>.jar /etc/init.d/<applicationname>
Once this is done, you can start/stop/restart the application exactly as with any other service:
service <applicationname> start
Similarly, we can mark the application (service) to start automatically when the system boots:
update-rc.d <applicationname> defaults
Securing the service
As I've indicated, the init.d service will start the application with the user who owns the application. In this regard, it's important that this user has the necessary permissions for the application to behave correctly.
The user used to start the application should be one without login capability. We can use the following command to modify the shell and prevent login for the user:
chsh -s /usr/sbin/nologin <user>
We can change the application's owner user as follows:
chown <user>:<group> <applicationname>.jar
The application jar should only have read and execute permissions for its owner, so we change its attributes:
chmod 500 <applicationname>.jar
In the end, we should have a structure like the following:

Installation as systemd service
Nowadays, most Linux distributions use systemd to manage system processes. Unlike SystemV where startup parameters are by convention, in the case of systemd it's by configuration, so to enable a service it's necessary to create a configuration script.
Configuration script
Scripts are located in the /etc/systemd/service
directory,
so for our application we'll need to create a file called /etc/systemd/service/<applicationname>.service
like the following:
[Unit]
Description=<applicationname>
After=syslog.target
[Service]
User=<executoruser>
ExecStart=/path/to/application/<applicationname>.jar
SuccessExitStatus=143
[Install]
WantedBy=multi-user.target
To mark the service to start automatically when the system boots, we'll use the following command:
sudo systemctl enable applicationname.service
Conclusion
In this post I've shown you how to configure a Spring Boot application to run as a service on Linux. I've shown two methods, one for older systems that use System V and another for newer systems that use systemd.
References
- https://stackoverflow.com/questions/21503883/spring-boot-application-as-a-service
- https://docs.spring.io/spring-boot/docs/current/reference/html/deployment.html#deployment-initd-service
- https://www.freedesktop.org/software/systemd/man/systemd.service.html
