Running Spring Boot app as a service in unix

Upasana | May 20, 2019 | 3 min read | 4,494 views


You should never run a Spring Boot application as root, so your application’s jar file should never be owned by root. Instead, create a specific user to run your application and use chown to make it the owner of the jar file

Creating executable Jar

We can always run Spring Boot applications by using java -jar <jarname> command, but it is also possible to make fully executable applications for Unix systems (centos, ubuntu, etc) that can be executed like any other executable binary and even registered with systemd. This makes it easy to install and manage Spring Boot applications in production environment.

Spring boot 1.x and 2.x have slightly different way of creating fully executable jars. We will explore both the options:

Spring Boot 1.x

The following configuration is required in build.gradle file in Spring Boot 1.x projects.

build.gradle
jar {
    baseName = 'your-app'
    version = version
}

springBoot {
    buildInfo()
    executable = true   (1)
    mainClass = "com.shunya.App"
}
1 This is required to make fully executable jar on unix system (Centos and Ubuntu)

Spring Boot 2.x

The following configuration in build.gradle will make a fully executable jar in Spring Boot 2.x project.

build.gradle
bootJar {
    launchScript()
    baseName = 'your-app'
    version =  '0.1.0'
}

Create a .conf file

If you want to configure custom JVM properties or Spring Boot application run arguments, then you can create a .conf file with the same name as the Spring Boot application name and place it parallel to jar file.

Considering that your-app.jar is the name of your Spring Boot application, then you can create the following file.

your-app.conf
JAVA_OPTS="-Xms64m -Xmx64m"
RUN_ARGS=--spring.profiles.active=prod
LOG_FOLDER=/custom/log/folder

This configuration will set 64 MB ram for the Spring Boot application and activate prod profile.

Create a new user in linux

For enhanced security we must create a specific user to run the Spring Boot application as a service.

Create a new user
sudo useradd -s /sbin/nologin springboot
On Ubuntu / Debian, modify the above command as follow:
sudo useradd -s /usr/sbin/nologin springboot
Set password
sudo passwd springboot
To reduce the chances of the application’s user account being compromised, you should consider preventing it from using a login shell. For example, you can set the account’s shell to /usr/sbin/nologin, this will limit your system’s attack surface.
Make springboot owner of the executable file
chown springboot:springboot your-app.jar
Prevent the modification of jar file
chmod 500 your-app.jar

This will configure jar’s permissions so that it can not be written and can only be read or executed by its owner springboot.

Octal 500 = read + execute (r-x) for owner, group has 0 and world has zero permissions.

You can optionally make your jar file as immutable using the change attribute (chattr) command.

sudo chattr +i your-app.jar
chattr +i sets the immutable filesystem attribute on the file. It differs from access control rules. Access controls are file attributes, immutable is a filesystem extended file attribute (may not be available). Only user with root privileges can set or unset this attribute.

Appropriate permissions should be set for the corresponding .conf file as well. .conf requires just read access (Octal 400) instead of read + execute (Octal 500) access

chmod 400 your-app.conf

Create Systemd service

/etc/systemd/system/your-app.service
[Unit]
Description=Your app description
After=syslog.target

[Service]
User=springboot
ExecStart=/var/myapp/your-app.jar
SuccessExitStatus=143

[Install]
WantedBy=multi-user.target

Automatically restart process if it gets killed by OS

Append the below two attributes (Restart and RestartSec) to automatically restart the process on failure.

/etc/systemd/system/your-app.service
[Service]
User=springboot
ExecStart=/var/myapp/your-app.jar
SuccessExitStatus=143
Restart=always
RestartSec=30

The change will make Spring Boot application restart in case of failure with a delay of 30 seconds. If you stop the service using systemctl command then restart will not happen.

Schedule service at system startup

To flag the application to start automatically on system boot, use the following command:

Enable Spring Boot application at system startup
sudo systemctl enable your-app.service

Start an Stop the Service

systemctl can be used in Ubuntu 16.04 LTS and 18.04 LTS to start and stop the process.

Start the process
sudo systemctl start your-app
Stop the process
sudo systemctl stop your-app

Top articles in this category:
  1. Setting a Random Port in Spring Boot Application at startup
  2. Run method on Spring Boot startup
  3. Spring Boot Sidecar
  4. Basic Auth Security in Spring Boot 2
  5. Redis rate limiter in Spring Boot
  6. Spring Boot multipart file upload server
  7. Feign RequestInterceptor in Spring Boot

Recommended books for interview preparation:

Find more on this topic: