Master systemd: From Basics to Real-World Service Management on Linux
This guide introduces systemd, explains its key features and unit file syntax, and provides three hands‑on examples showing how to manage Nginx, Tomcat, and a custom JAR application with systemd on modern Linux distributions.
systemd Overview
systemd is the primary init system and service manager on modern Linux distributions, replacing the traditional init because it supports parallel start‑up, better dependency handling, and richer unit management.
Key Features
Adopted by major distributions (RHEL 7, CentOS 7, Ubuntu 15…)
Parallel service start‑up improves boot speed
Shutdown only stops running services, unlike legacy init
Units are defined by configuration files instead of shell scripts
Handles lingering child processes that older service commands missed
systemd Command Syntax
<code>systemctl [command] [unit]</code>Common commands:
start – start a unit (e.g.,
systemctl start nginx)
stop – stop a unit
restart – restart a unit
reload – reload configuration
enable – enable unit at boot
disable – disable unit at boot
status – show unit status
Unit Configuration Files
Each unit has a
.servicefile that tells systemd how to manage it.
Files are stored in
/usr/lib/systemd/system/with symlinks in
/etc/systemd/systemafter enabling.
File name ends with
.service.
Two directories:
systemfor system‑wide services and
userfor per‑user services.
Configuration sections are case‑sensitive and enclosed in brackets.
Practical Example 1 – Managing Nginx with systemd
Install build dependencies and compile Nginx from source:
<code>yum -y install gcc gcc-c++ openssl-devel pcre-devel gd-devel iproute net-tools telnet wget curl
wget http://nginx.org/download/nginx-1.15.5.tar.gz
tar zxf nginx-1.15.5.tar.gz
cd nginx-1.15.5
./configure --prefix=/usr/local/nginx \
--with-http_ssl_module \
--with-http_stub_status_module
make -j 4 && make install</code>Start Nginx manually:
<code>/usr/local/nginx/sbin/nginx # start
/usr/local/nginx/sbin/nginx -s reload # reload
/usr/local/nginx/sbin/nginx -s quit # stop</code>Create a systemd service unit:
<code>[Unit]
Description=nginx
After=network.target
[Service]
Type=forking
ExecStart=/usr/local/nginx/sbin/nginx
ExecReload=/usr/local/nginx/sbin/nginx -s reload
ExecStop=/usr/local/nginx/sbin/nginx -s quit
PrivateTmp=true
[Install]
WantedBy=multi-user.target</code>Control the service with
systemctl:
<code>systemctl restart nginx
systemctl enable nginx
systemctl stop nginx</code>Practical Example 2 – Managing Tomcat with systemd
Install JDK and extract Tomcat:
<code>wget 120.78.77.38/file/jdk-8u231-linux-x64.rpm
rpm -ivh jdk-8u231-linux-x64.rpm
wget 120.78.77.38/file/apache-tomcat-9.0.27.tar.gz
tar -xf apache-tomcat-9.0.27
mv apache-tomcat-9.0.27 /usr/local/tomcat</code>Start and stop Tomcat manually:
<code>/usr/local/tomcat/bin/startup.sh # start
/usr/local/tomcat/bin/shutdown.sh # stop</code>Create
/usr/lib/systemd/system/tomcat.service:
<code>[Unit]
Description=tomcat server
Wants=network-online.target
After=network.target
[Service]
Type=forking
Environment="JAVA_HOME=/usr/java/jdk1.8.0_231-amd64"
Environment="PATH=$JAVA_HOME/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/root/bin"
Environment="CLASSPATH=.:$JAVA_HOME/lib/dt.jar:$JAVA_HOME/lib/tools.jar"
ExecStart=/usr/local/tomcat/bin/startup.sh
ExecStop=/usr/local/tomcat/bin/shutdown.sh
Restart=on-failure
[Install]
WantedBy=multi-user.target</code>Manage Tomcat with systemd:
<code>systemctl restart tomcat
systemctl enable tomcat
systemctl stop tomcat
systemctl status tomcat</code>Practical Example 3 – Managing a Custom JAR Application
Sample command to run the JAR:
<code>java -jar decode.jar -Dconfig=/usr/local/abc/application.properties</code>Create a simple start/stop script (
demo.sh) and a corresponding systemd unit (
abc.service).
<code># demo.sh
#!/bin/bash
source /etc/profile
jarName="abc-web.jar"
workDir="/usr/local/abc"
start() {
cd ${workDir} && java -jar ${jarName} --spring.profiles.active=prod --server.port=9630 >uams.log 2>&1 &
}
stop() {
ps -ef | grep -qP "(?<=-jar)\s+${jarName}" && kill $(ps -ef | grep -P "(?<=-jar)\s+${jarName}" | awk '{print $2}')
}
case $1 in
start) start ;;
stop) stop ;;
restart) stop; start ;;
esac
</code>Systemd unit file:
<code>[Unit]
Description=uams server
Wants=network-online.target
After=network.target
[Service]
Type=forking
WorkingDirectory=/usr/local/abc/
ExecStart=/bin/bash demo.sh start
ExecStop=/bin/bash demo.sh stop
ExecReload=/bin/bash demo.sh restart
Restart=on-failure
[Install]
WantedBy=multi-user.target</code>Control the custom service:
<code>systemctl restart abc
systemctl enable abc
systemctl stop abc
systemctl status abc</code>Efficient Ops
This public account is maintained by Xiaotianguo and friends, regularly publishing widely-read original technical articles. We focus on operations transformation and accompany you throughout your operations career, growing together happily.
How this landed with the community
Was this worth your time?
0 Comments
Thoughtful readers leave field notes, pushback, and hard-won operational detail here.