Deploying Spring Boot Applications as Systemd Services on Linux
Stop using nohup. Learn the professional way to manage your Java applications with auto-restart, logging, and background execution.
Introduction
When developing a Spring Boot application, you typically run it using java -jar app.jar or mvn spring-boot:run. However, on a production server, this approach has problems:
- If you close the terminal, the app stops.
- Using nohup (e.g., nohup java -jar ... &) is unreliable and makes stopping the app difficult.
- If the server reboots, the app won't start automatically.
The standard Linux solution is to create a Systemd Service. This allows Linux to manage your application just like it manages Nginx, MySQL, or SSH.
Step 1: Install the JDK
First, ensure Java is installed on your server. We will use OpenJDK 17 for this example, but you can use version 11 or 21 depending on your project.
Update your package list and install the JDK:
xinit@localhost:~$ sudo apt update && sudo apt install openjdk-17-jdk -y
Step 2: Locate the Java executable
Systemd requires absolute paths for all commands. We cannot just write java; we need the full path to the binary.
Find the location of your java executable:
xinit@localhost:~$ which java
Result: You should see output like /usr/bin/java. Remember this path.
Step 3: Create the Service file
Systemd configuration files are located in /etc/systemd/system/. We will create a new file named after your project (e.g., myapp.service).
Open a new service file in the text editor:
xinit@localhost:~$ sudo nano /etc/systemd/system/myapp.service
Paste the following configuration into the file. Important: Replace User=user with your actual Linux username (e.g., root, ubuntu, or a dedicated spring user) and update the paths to your .jar file.
[Unit]
Description=My Spring Boot Application
After=syslog.target network.target
[Service]
# The user who will run the application
User=your_linux_username
# The command to start the app.
# 1. Use absolute path for java (/usr/bin/java)
# 2. Point to your JAR file
# 3. (Optional) Point to an external config file
ExecStart=/usr/bin/java -jar /home/your_linux_username/project/app.jar --spring.config.location=/home/your_linux_username/project/application.properties
# If the app crashes, restart it automatically
Restart=always
RestartSec=10
# Spring Boot exits with code 143 on SIGTERM (standard stop),
# tell Systemd this is a normal exit.
SuccessExitStatus=143
[Install]
WantedBy=multi-user.target
Save and close the file (Ctrl+O, Enter, Ctrl+X).
Step 4: Reload Systemd
Since we created a new unit file, we must tell the Systemd manager to reload its configuration and look for new services.
Reload the daemon configuration:
xinit@localhost:~$ sudo systemctl daemon-reload
Step 5: Enable and start the Service
Now we can manage our application.
First, enable the service so it starts automatically when the server boots up:
xinit@localhost:~$ sudo systemctl enable myapp.service
Now, start the service immediately:
xinit@localhost:~$ sudo systemctl start myapp.service
Step 6: Check status and logs
How do you know if it's working? Never guess; always check the status.
Check the current status of your service:
xinit@localhost:~$ sudo systemctl status myapp.service
You should see a green dot and Active: active (running).
To view the application logs (equivalent to seeing the terminal output), use journalctl. The -u flag specifies the unit, and -f follows the logs in real-time.
View live application logs:
xinit@localhost:~$ sudo journalctl -u myapp.service -f
(Press Ctrl+C to exit the log view).
Conclusion
You have successfully deployed your Spring Boot application as a Systemd service. Your app will now:
- Start automatically on reboot.
- Restart automatically if it crashes.
- Write logs to the system journal for easy debugging.