Wednesday, February 19, 2025

How to Create a Custom Systemd Service in Linux

https://www.maketecheasier.com/create-custom-systemd-service-in-linux

How to Create a Custom Systemd Service in Linux

A photograph of a person working in front of his computer.

Systemd is a powerful and highly versatile init system for Linux distros. It can run programs, manage system resources, and even control the state of your computer. In this article, I’ll demonstrate how you can use Systemd to control your apps by creating a custom service unit in Ubuntu.

What is a Systemd Service Unit?

A service unit is a regular file that contains details on how to run a specific app. It includes the general metadata of the program, how to run it, and whether Systemd can access it on a regular session.

By default, every daemon on a Systemd-based machine has some form of a service file. OpenSSH, for instance, uses the ssh.service unit in “/etc/systemd/system/” to determine how it will run in Debian and Ubuntu.

A terminal showing the service unit for OpenSSH.

At a basic level, a service unit file is made up of three parts: the Unit, Service, and Install categories. The Unit section provides the app’s metadata and dependencies. The Service section defines where the app is and how Systemd will run it. Lastly, the Install section describes when can Systemd start the app.

Creating a System-level Custom Systemd Service

One of the most common uses for a custom service is automating commands that require root privileges or take advantage of Systemd Timers. For instance, a custom service helps in ensuring that a Minecraft server will start up properly after a restart.

To create a custom system-level service in Linux, start by making the Systemd unit file in your user’s home directory:

nano ~/my-system-app.service

Paste the following block of code inside your new unit file. This is the simplest valid config for a Systemd service:

[Unit]
Description=My First Service
After=network.target
 
[Service]
Type=simple
ExecStart=/path/to/bin
Restart=always
 
[Install]
WantedBy=multi-user.target

Replace the “Description” variable with the details of your user-level service.

Replace the “ExecStart” variable with the full file path of program that you want to run.

A terminal showing a simple Systemd unit file for a system-level service.

Save your new file, then copy it to your machine’s services directory:

sudo cp ./my-system-app.service /etc/systemd/system/

Run the following command to restart the Systemd daemon:

sudo systemctl daemon-reload

Test your new system-level service by running the following command:

sudo systemctl start my-system-app.service

Lastly, confirm that your new service is running properly by checking its status in systemctl:

systemctl status my-system-app.service
A terminal showing the custom service running properly.

Creating a User-level Custom Systemd Service

Service units aren’t limited to system-level apps or superusers. With the help of Systemd-user, it’s possible to create rootless services. This allows non-root users to manage local apps while improving their PC’s security by limiting programs with root access.

To create your user-level custom service in Linux, make a new Systemd unit file in your user’s home directory:

nano ~/my-user-app.service

Paste the following block of code inside your new unit file:

[Unit]
Description=My First User Service
After=graphical-session.target
 
[Service]
Type=simple
ExecStart=/path/to/bin
 
[Install]
WantedBy=default.target

Replace the value of the “ExecStart” variable to the path of the program that you want to run. Since this is a user-level service, make sure that your user account has proper access to the binary.

A terminal highlighting the user script with regular user access.

Save your new user-level service file, then create the local Systemd directory for your user:

mkdir -p ~/.config/systemd/user/

Copy your new user-level service file to the local Systemd directory for your user:

cp ./my-user-app.service ~/.config/systemd/user/

Make sure that Systemd checks your user directory for new service unit files:

systemctl daemon-reload --user

Lastly, confirm that your new service is running properly by checking its status in systemctl:

systemctl --user status my-user-app.service
A terminal showing the custom user service recognized in systemctl.

Good to know: Systemd is more than just an init system. Learn how its sister program: Systemd-boot stacks against the popular GRUB.

Tweaking Your Custom Systemd Service

One of the core strengths of Systemd is that it allows you to fully customize how to run and manage programs.

Adding Environment Variables to a Custom Service

Environment variables are an important part of every Linux system. They provide additional data to a program without fiddling with config files. With Systemd, it’s possible to make use of environment variables by incorporating it to your service units.

Start by disabling the service that you want to modify:

systemctl --user disable --now my-user-app.service

Open your custom service file using your favorite text editor:

sudo nano ~/.config/systemd/user/my-user-app.service

Scroll to the “[Service]” section, then add the following line of code just below the “Type=” variable:

Environment=""

Add the environment variable that you want to add to your custom service. In my case, I want to add an EDITOR variable to make sure that my service sees my Vim instance.

A terminal showing a service with a modified environment variable.

Save your modified service file, then reload your Systemd daemon to apply your changes.

A terminal showing the process of reloading the Systemd daemon.

Restart your new Systemd service to make use of your new environment variable:

systemd --user start my-user-app.service

Restricting Custom Service to a Specific User

Apart from user-level unit files, you can also tweak a system-level service to run under a specific user. This is helpful if you want to run an app under a rootless and shell-less user account.

To bind a Systemd service to a user, first completely disable your custom unit.

A terminal showing the details of a fully disabled service.

Make sure that the target user account already exists on your machine.

A terminal showing the existence of a user for the Systemd unit.

Open your system-level service file using your favorite text editor:

sudo nano /etc/systemd/system/my-system-app.service

Scroll down to the “[Service]” section, then add the “User=” variable followed by the name of your user account.

A terminal highlighting the User= value inside the custom service file.

Note: you can also specify the group for your service by adding “Group=” below the User variable.

Save the changes on your unit file, then restart the service:

sudo systemctl start my-system-app.service

Confirm that your service is now running as your user by running the following command:

ps -o user= -p $(systemctl show my-system-app.service -p MainPID | awk -F= '{print $2}')
A terminal showing the current owner of the system process.

Limiting a Service Unit’s Resource Consumption

On top of tweaking environment variables and users, Systemd can limit the resources an app can consume over its lifespan. While it doesn’t do it by default, it’s possible to control core parts such as CPU usage and overall process count.

Begin by completely disabling the service that you want to tweak.

A terminal showing a disabled system service.

Open the service unit file using your favorite text editor:

sudo nano /etc/systemd/system/my-system-app.service

Scroll down to the “[Service]” section, then add the variable name for the resource that you want to limit. For instance, adding the “MemoryHigh=” variable allows you to set a soft memory limit for that service.

A terminal highlighting the modified MemoryHigh value for the custom service.

Tip: You can find a list of valid variables by running man systemd.resource-control on a terminal session.

Save your unit file, then reload your Systemd service:

sudo systemctl enable --now my-system-app.service

Lastly, you can monitor your running services by running systemd-cgtop.

A terminal showing the output of systemd-cgtop.

Learning how to create custom Systemd services and modifying them to your needs is just the step in understanding this highly versatile tool. Explore more of Systemd and what its comprehensive ecosystem can do by checking out how Run0 performs against Sudo.


  • No comments:

    Post a Comment