The Shepherd is a service manager written in Guile Scheme that looks after the herd of daemons running on the system. It can be used as an “init” system (PID 1) and also by unprivileged users to manage per-user daemons. It supports several daemon startup mechanisms—including inetd, systemd-style socket activation, and timers—and comes with a handy collection of services: syslog, log rotation, and more. The Shepherd is configured in Guile Scheme and can be extended in the same language. It builds on a simple memory-safe and callback-free programming model.
The Shepherd is developed jointly with Guix. It runs as PID 1 on Guix System and manages user services for Guix Home.
What does it look like?
The
herd
command interacts with a running
shepherd
process; as a user or system administrator, it is your entry point to
service management:
# herd status sshd
● Status of ssh-daemon:
It is running since Mon 21 Oct 2024 10:02:52 AM CEST (5 days ago).
Inetd-style service listening on 2 endpoints:
- 0.0.0.0:22
- [::]:22
It is enabled.
Provides: ssh-daemon ssh sshd
Requires: pam syslogd loopback networking
Custom action: configuration
Will be respawned.
$ sudo herd status tor
● Status of tor:
It is running since Mon 02 Dec 2024 09:06:26 AM CET (3 days ago).
Main PID: 257
Command: /gnu/store/r6yp8g0mjxmdd26hvl01byp2zm41bj5h-tor -f /gnu/store/aj4qbf1rmk1bhn48alfmnwh018k48hw0-torrc
It is enabled.
Provides: tor
Requires: user-processes loopback syslogd
Custom action: configuration
Will be respawned.
Recent messages (use '-n' to view more or less):
2024-12-04 20:16:28 Dec 04 20:16:28.000 [notice] We now have enough directory information to build circuits.
2024-12-04 21:23:25 Dec 04 21:23:25.000 [notice] Heartbeat: Tor's uptime is 1 day 17:59 hours, with 18 circuits open. I've sent 53.59 MB and received 272.47 MB. I've received 1732 connections on IPv4 and 0 on IPv6. I've made 45 connections with IPv4 and 0 with IPv6.
2024-12-04 21:23:25 Dec 04 21:23:25.000 [notice] While not bootstrapping, fetched this many bytes: 355778 (consensus network-status fetch); 789909 (microdescriptor fetch)
$ herd status log-rotation
● Status of log-rotation:
It is running since 05:59:48 PM (6 hours ago).
Timed service.
Periodically running Scheme code.
It is enabled.
Provides: log-rotation
Custom actions: trigger files
Will not be respawned.
Upcoming timer alarms:
Sun 08 Dec 2024 10:00:00 PM CET (in 4 days)
Sun 15 Dec 2024 10:00:00 PM CET (in 11 days)
Sun 22 Dec 2024 10:00:00 PM CET (in 18 days)
Sun 29 Dec 2024 10:00:00 PM CET (in 25 days)
Sun 05 Jan 2025 10:00:00 PM CET (in 32 days)
$ sudo herd status system-log
● Status of system-log:
It is running since Mon 02 Dec 2024 09:06:23 AM CET (3 days ago).
Running value is "#<system-log 7fcb03a9fb00>".
It is enabled.
Provides: system-log syslogd
Will not be respawned.
Log files: /var/log/messages /dev/tty12 /var/log/debug /var/log/secure /dev/console
Recent messages (use '-n' to view more or less):
2024-12-04 23:43:08 localhost shepherd[1]: /var/log/ntpd.log ntpd
2024-12-04 23:43:08 localhost shepherd[1]: /var/log/guix-daemon.log guix-daemon
2024-12-04 23:43:08 localhost sudo: pam_unix(sudo:session): session closed for user root
2024-12-04 23:44:21 localhost sudo: ludo : TTY=pts/0 ; PWD=/home/ludo/src/guix ; USER=root ; COMMAND=/home/ludo/.guix-home/profile/bin/herd status system-log
2024-12-04 23:44:21 localhost sudo: pam_unix(sudo:session): session opened for user root(uid=0) by (uid=1000)
# herd files log-rotation
/var/log/messages system-log
/dev/tty12 system-log
/var/log/debug system-log
/var/log/secure system-log
/dev/console system-log
/var/log/guix-publish.log guix-publish
/var/log/avahi-daemon.log avahi-daemon
/var/log/dbus-daemon.log dbus-system
/var/log/ntpd.log ntpd
/var/log/guix-daemon.log guix-daemon
As a system administrator or distro developer, you define services in a configuration file written in Scheme:
(define sshd
(service
'(sshd ssh-daemon) ;the secure shell daemon
#:start (make-inetd-constructor ;start on demand
'("/usr/sbin/sshd" "-D" "-i")
(list (endpoint
(make-socket-address AF_INET INADDR_ANY 22))
(endpoint
(make-socket-address AF_INET6 IN6ADDR_ANY 22)))
#:max-connections 10)
#:stop (make-inetd-destructor)
#:respawn? #t))
(register-services (list sshd))
(start-in-the-background '(sshd))
New to Scheme? Get started in a few minutes with the Scheme Crash Course.
From writing your configuration to extending the Shepherd, and from
extending it to contributing to it, there’s only a small
step. An entire programming
interface
is at your disposal; if you’re adventurous, you can even fiddle with a
running
shepherd
!
Concurrency in shepherd
is made simple by following the concurrent
sequential processes (CSP)
model
using Fibers. Surely, that makes it
the coolest init system to hack on.
Licensing
The Shepherd is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License, version 3 or any later version.
History
The Shepherd was formerly known as GNU dmd. dmd was initially developed by Wolfgang Jährling, with input from other GNU hackers. It was first released in 2003, making it one of the first init systems departing from the venerable System V approach. Its development was then closely related to the GNU Hurd, although it has always supported GNU/Linux as well.
After a looong period of freeze, it was revived in 2013. It saw its first positively-numbered release in December 2013. It has since been used as the init system (PID 1) of Guix System.
In January 2016, GNU dmd was renamed to GNU Shepherd to avoid confusion with a same-named project.
Credits
The Shepherd’s logo was designed by Luis Felipe López Acevedo. The graphics are Copyright © 2024 Luis Felipe López Acevedo and distributed under the terms of the CC-BY-SA 4.0 license.
Stylesheet derived from earlier work by Ricardo Wurmus.