This is my user configuration for Shepherd. I use Shepherd not only to run my user daemons, but also to start X sessions, window managers, various GUI utils and applications.
Shepherd is a great program for managing user services. Previously I used Systemd for this purpose (see my systemd-user-units repository), but Shepherd is a much more convenient tool because you have a whole power of a general-purpose language (Guile) in your hands. It’s like comparing Emacs and nano: with Emacs you can program your environment, while with nano… well, you can probably do some text editing in nano, I don’t want to hurt nano fans.
My config consists of a single init.scm
file which uses some of my
guile modules.
There is nothing interesting with the usual daemons (like gpg-agent or
dbus), except maybe that I have a “target” service daemons
that allows
me to control all the daemons at once, like this [fn:1]:
herd status daemons
herd stop daemons
GUI services are more interesting. At first, there is a problem: after starting X server, we should wait for some time, and only when it is ready, we can start window manager and other programs on it. Thanks to Jouke Witteveen there is a beautiful solution for this problem: a bash script that runs X server as a daemon. I made a stand-alone package for this Xdaemon script here.
Another obstacle for me was that I wanted to start X server with my
configuration and modules placed in non-standard directories, but Xorg
does not allow this when it is run with elevated rights. Although
recent Xorg versions have some support to be started with non-super-user
rights, I’m not able to use this feature, so the only option I see is to
start X server with sudo
. So I configured /etc/sudoers so that
Xdaemon script (installed to an unmodifiable global directory) could be
run with sudo without password.
Now if I run the following command [fn:2]:
herd start gui:0
X server is started on DISPLAY :0 and vt7, then some auxiliary services are started (xset, xmodmap, etc.), and finally xterm (as I didn’t specify anything after “gui:0”).
If I run this:
herd start gui:1 stumpwm emacs
Another X server is started on DISPLAY :1 and vt8, and instead of xterm I got stumpwm and emacs running on this DISPLAY.
Then I can stop services, restart services, start another window manager on a particular display, and do other service managing tasks. Shepherd is not as mature as systemd and is not very well documented, but it is really great!
[fn:1] Actually instead of writing herd start/status/…
I just write
start/status/…
as I have several shell aliases for herd commands that
can be found here.
[fn:2] For more convenience I wrote a wrapper guile script that allows me to start X server and other things on a free DISPLAY.