Creating the Systemd Unit

Systemd is a process manager that can start, stop, and manage processes ("Units") on boot or shutdown of your machine![1] In this walkthrough, we'll be starting a long-running Node.js web server that lives in /var/www/.

To create a new Unit, we need to create a file in /etc/systemd/system/ (the default location on most Linux distributions). This file should have the .service extension.

Let's create /etc/systemd/system/webserver.service:

[Unit]
# Since we're going to bind to a port on localhost, we need to wait for the
# network to be available:
After=network.target
Description=My fancy web server

[Service]
# Set the working directory to where your application lives
WorkingDirectory=/var/www
# Set any environment variables your application needs
Environment=NODE_ENV=production
Environment=PORT=3000
# Start your webserver (absolute path required - find yours with `which node`)
ExecStart=/usr/bin/node server.js
# Restart the service if it crashes
Restart=always
# Wait 3 seconds before restarting
RestartSec=3

[Install]
# Start this service when the system boots to multi-user mode
WantedBy=multi-user.target

After you've created the file, update it to have the correct permissions (664):

chmod 664 /etc/systemd/system/webserver.service

Don't be intimidated by the file above! A lot of it is boilerplate. Read the comments placed in the above file to understand what each section is for!

Note: Comments in systemd unit files must be on their own line—inline comments after values are not supported.[2] The ExecStart directive requires an absolute path to the executable.[3]

You can learn more about the Unit or Service sections in the systemd documentation.

The Install section is used to configure when the service will start. Most commonly, you'll want multi-user.target.[4] The WantedBy value directly corresponds to different Linux runlevels:

runlevel WantedBy value Description
0 poweroff.target Run before the computer shuts down
1 rescue.target Run when the system is in single-user mode
2-4 multi-user.target Non-graphical multi-user system (networking available)
5 graphical.target Run when the display manager has started
6 reboot.target Run before the computer reboots

Enabling the Systemd Unit

Now that the unit has been created, we need to reload the Systemd process. This will allow Systemd to recognize the new file.

Run the following command:

systemctl daemon-reload

Tip: You need to execute the above command to reload Systemd every time you edit your .service file(s).

Next, you'll need to enable the service. Running this command will create a symlink into your WantedBy target.

systemctl enable webserver

Finally, since your system is already booted, run the following command to start the service:

systemctl start webserver

Cheatsheet

Enabling (creating) or Disabling (deleting) your service

systemctl enable webserver # enable service to start on boot
systemctl disable webserver # disable service from starting on boot

Starting, Restarting, or Stopping your service

systemctl start webserver
systemctl restart webserver
systemctl stop webserver

Checking the status of your service

systemctl status webserver

[1] freedesktop.org. "systemd.unit — Unit configuration". systemd documentation.

[2] freedesktop.org. "systemd.syntax — General syntax of systemd configuration files". "Lines beginning with '#' or ';' are ignored."

[3] freedesktop.org. "systemd.service — Service unit configuration". "The first argument must be either an absolute path or a simple file name without any slashes."

[4] Red Hat. "Working with systemd unit files". RHEL 9 Documentation.