How to Create Custom systemd Units on Debian 12 Bookworm

Learn how to create custom systemd units on Debian 12 Bookworm.

Systemd is the default system and service manager for most modern Linux distributions, including Debian 12 Bookworm. It manages system processes, services, mounts, sockets, and much more. One of systemd’s powerful features is the ability to define custom unit files, allowing administrators to create and control their own services with precision.

In this article, we’ll explore how to create custom systemd units, understand their structure, and manage them effectively on a Debian 12 system. Whether you want to run a shell script as a service or create a daemon for a specific task, systemd makes it straightforward—once you understand the basics.


What is a systemd Unit?

A systemd unit is a configuration file that tells systemd how to manage a particular resource. These resources can be:

  • Services (.service)
  • Mount points (.mount)
  • Devices (.device)
  • Sockets (.socket)
  • Targets (.target)
  • Timers (.timer)
  • Paths (.path)
  • And more

The most common unit type is the service unit, used to start, stop, and manage long-running processes like daemons and background tasks.


Why Create a Custom systemd Unit?

You may want to create a custom systemd unit in the following scenarios:

  • Running your own script or application as a background service
  • Automating a startup process
  • Managing third-party software not installed via Debian’s package manager
  • Replacing traditional SysV init scripts with modern systemd units

Creating a custom unit gives you complete control over the environment, behavior, and dependencies of your service.


Prerequisites

Before you begin, make sure you:

  • Are running Debian 12 Bookworm
  • Have sudo or root privileges
  • Have basic knowledge of shell scripting and Linux file system hierarchy

Step-by-Step: Creating a Custom systemd Service Unit

Let’s walk through the process of creating a custom systemd service unit on Debian 12. For this example, we’ll create a simple script that logs the current date and time to a file every time it starts.

1. Create a Script to Manage

Let’s start by writing the shell script we want to run as a service:

sudo mkdir -p /opt/custom-services
sudo nano /opt/custom-services/log-time.sh

Paste the following contents into the file:

#!/bin/bash
# Simple script to log current time to a file

LOGFILE="/var/log/custom-time.log"

echo "[$(date)] Service started." >> "$LOGFILE"

Make it executable:

sudo chmod +x /opt/custom-services/log-time.sh

Make sure the log file can be written by the service:

sudo touch /var/log/custom-time.log
sudo chown root:root /var/log/custom-time.log

2. Create the systemd Service File

Systemd unit files live in /etc/systemd/system/ for user-defined services. Let’s create our custom unit:

sudo nano /etc/systemd/system/log-time.service

Paste the following unit definition:

[Unit]
Description=Custom Time Logging Service
After=network.target

[Service]
Type=oneshot
ExecStart=/opt/custom-services/log-time.sh
User=root
Group=root

[Install]
WantedBy=multi-user.target

Explanation of Sections

  • [Unit]

    • Description: A human-readable description.
    • After: Ensures this service starts after the network is up.
  • [Service]

    • Type=oneshot: The script runs once and exits. Use simple or forking for daemons.
    • ExecStart: The script to run.
    • User and Group: Optional but useful for security.
  • [Install]

    • WantedBy=multi-user.target: This ensures the service starts during normal boot in multi-user mode.

3. Reload systemd and Enable the Service

Whenever you add or modify a systemd unit, you must reload the daemon:

sudo systemctl daemon-reexec
sudo systemctl daemon-reload

Now, start and enable the service:

sudo systemctl start log-time.service
sudo systemctl enable log-time.service

Check the status:

sudo systemctl status log-time.service

You should see output indicating the service ran successfully.

To check the log output:

cat /var/log/custom-time.log

Making the Service Persistent or Repeating

If you want the service to repeat periodically, you can use a .timer unit.

1. Create a Timer Unit

Create a new file:

sudo nano /etc/systemd/system/log-time.timer

Add the following contents:

[Unit]
Description=Run log-time.service every 15 minutes

[Timer]
OnBootSec=5min
OnUnitActiveSec=15min
Unit=log-time.service

[Install]
WantedBy=timers.target

Reload and enable:

sudo systemctl daemon-reload
sudo systemctl start log-time.timer
sudo systemctl enable log-time.timer

Now, the script will execute every 15 minutes.

To view the timer:

systemctl list-timers

Other Useful Directives

Here are some additional directives you may want to use in your custom unit files:

Restart Behavior

To keep a service running if it fails:

Restart=on-failure
RestartSec=5

Logging

You can view logs with journalctl:

journalctl -u log-time.service

To enable standard output to be logged in the journal:

StandardOutput=journal
StandardError=journal

Environment Variables

If your service needs environment variables:

Environment="ENV_VAR=value"

Or load from a file:

EnvironmentFile=/etc/myapp/env.conf

Cleaning Up and Disabling

To disable and stop a service:

sudo systemctl disable log-time.service
sudo systemctl stop log-time.service

To remove it completely:

sudo rm /etc/systemd/system/log-time.service
sudo rm /etc/systemd/system/log-time.timer
sudo systemctl daemon-reload

Tips and Best Practices

  • Always test your unit files before enabling them.
  • Use systemd-analyze to debug boot performance.
  • Separate user and system units—user-level units go in ~/.config/systemd/user/.
  • Always document your custom services for future maintenance.
  • Consider security by specifying a non-root User= whenever possible.

Conclusion

Custom systemd units provide a robust and modern way to manage scripts and services on a Debian 12 Bookworm system. Whether you’re deploying a web app, scheduling backups, or running periodic scripts, systemd offers powerful tools for automation and control.

In this guide, we created a simple log-time.service, enabled a corresponding timer, and reviewed advanced configuration options. With this foundation, you can confidently write and manage your own services tailored to your specific needs.

By mastering custom unit creation, you take a big step toward becoming a proficient Linux system administrator.