Lesson 13 of 30 intermediate 4 min read

Before this:Build artifacts & versioning

Services & systemd

Key takeaways A service is a program that runs in the background, starts on boot, and restarts if it crashes. On Linux, systemd manages services: you describe one in a unit file and control it with systemctl. GopherTrunk ships a real unit that starts the scanner on boot, restarts it on failure, and locks it down with hardening — the non-container way to run in production.

Containers are one way to run in production; a plain binary managed by systemd is the other. This lesson turns a binary into a proper service.

From a binary to a service

Run ./gophertrunk in your terminal and it dies when you log out or it crashes. A production service needs to:

  • start automatically on boot,
  • restart itself if it fails,
  • run in the background independent of any login,
  • log somewhere you can read later.

On Linux, systemd provides all of this. You describe your service once in a unit file and systemd handles the rest. (The Linux CLI module covers systemd basics; here we focus on deploying with it.)

GopherTrunk’s unit file

Here’s the heart of the unit GopherTrunk ships:

[Unit]
Description=GopherTrunk digital trunking scanner
After=network-online.target
Wants=network-online.target

[Service]
Type=exec
ExecStart=/usr/local/bin/gophertrunk run -config /etc/gophertrunk/config.yaml
Restart=on-failure
RestartSec=5

[Install]
WantedBy=multi-user.target

Reading it top to bottom:

  • [Unit] — a description and ordering: start after the network is online.
  • ExecStart — the exact command to run, pointing at the installed binary and its config file.
  • Restart=on-failure with RestartSec=5 — if it crashes, wait 5 seconds and restart. This is your crash resilience.
  • WantedBy=multi-user.target — enable it and it starts on every boot.

Installing and controlling it

Install the unit and binary, then manage the service with systemctl:

sudo install -m 0644 docs/gophertrunk.service /etc/systemd/system/gophertrunk.service
sudo install -m 0755 bin/gophertrunk /usr/local/bin/gophertrunk
sudo systemctl daemon-reload
sudo systemctl enable --now gophertrunk   # start now AND on every boot
sudo systemctl status gophertrunk         # check it's running

enable --now is the key line: it starts the service immediately and wires it to start on boot.

Locking it down

A production service should run with the least privilege it needs. GopherTrunk’s real unit adds a raft of hardening directives — a taste:

DynamicUser=true            # run as an unprivileged, ephemeral user
ProtectSystem=strict        # the filesystem is read-only except...
ReadWritePaths=/var/lib/gophertrunk
NoNewPrivileges=true        # can never gain new privileges
ProtectKernelModules=true
RestrictRealtime=true

These tell the kernel to run the scanner in a tightly confined sandbox — it can’t write outside its data directory, can’t escalate privileges, can’t touch kernel internals. It’s the same least-privilege instinct as the container’s dropped capabilities, applied to a bare-metal service, and it connects directly to the cybersecurity module.

Quick check: which systemd setting makes a service restart itself after it crashes?

Recap

  • A service runs in the background, starts on boot, and restarts on failure.
  • systemd manages services via a unit file; systemctl controls them.
  • GopherTrunk’s unit sets ExecStart, Restart=on-failure, and WantedBy=multi-user.target — plus hardening for least privilege.
  • systemctl enable --now starts a service immediately and on every boot.

Next up: how a running service tells you it’s healthy — logging and health checks.

Frequently asked questions

What is systemd?

systemd is the init and service manager on most modern Linux systems. It starts services at boot, restarts them if they crash, manages their dependencies and ordering, and collects their logs. You describe a service in a unit file and control it with systemctl commands like start, stop, enable, and status.

How is running under systemd different from just running a binary?

Running a binary in your terminal stops the moment you log out or the program crashes. A systemd service runs in the background, starts automatically on boot, restarts on failure, logs to the journal, and can be locked down with security settings — everything a long-running production service needs.