Whenever a daemon file is changed in /etc/systemd/system/, the daemon files must be reloaded with:
systemctl daemon-reload
Most *nix derivates start a login program such as getty on multiple virtual terminals for the user to log-in when the system boots. On pre-systemd systems, /etc/inittab was used to spawn (and re-spawn) getty on the virtual terminals, which could also be used to run console programs such as htop instead of the login terminal.
The procedure with systemd is a little different and involves shutting down the tty services and creating a service file. The first thing to do is run:
systemctl
and search (using forward-slash / and typing in text to search) for getty. On a Debian system, one would find:
getty@tty1.service loaded active running Getty on tty2 getty@tty2.service loaded active running Getty on tty2 getty@tty6.service loaded active running Getty on tty6
which means that getty will be spawned on tty1, tty2 and tty6. Whilst tty6 has a special meaning and is a fallback console to always provide the means for an operator to log-in, tty1 and tty2 could be used to spawn a different program such as htop.
In order for getty and htop to not race each other, the first step is to stop and disable the getty@tty1.service service:
systemctl stop getty@tty1.service systemctl disable getty@tty1.service
Next, add the following contents to a file placed at /etc/systemd/system/htop.service:
[Unit] Description=htop on tty1 [Service] Type=simple ExecStart=/usr/bin/htop StandardInput=tty StandardOutput=tty TTYPath=/dev/tty1 Restart=always RestartSec=2 [Install] WantedBy=getty.target
where:
/dev/tty1 is the virtual terminal to start htop on.You can now enable and start the service via:
systemctl enable htop.service
systemctl start htop.service
and htop should appear on the first virtual terminal.
The SystemD version of init 3:
systemctl isolate multi-user.target
and the init 4 version:
systemctl isolate graphical.target
Given a service file and a network interface (for example, br0), the service file can be modified such that the service file runs only after the network interface (br0) is up and running.
In order to do so, issue the command:
systemctl list-units --no-pager
that will list all the systemd units and look for br0. 
If it is a configured network interface, then something along the lines:
sys-devices-virtual-net-br0.device loaded active plugged /sys/devices/virtual/net/br
will be printed by the previous command.
In order to modify the service file, add sys-devices-virtual-net-br0.device to the [Unit] section of the service file:
[Unit] BindsTo=sys-devices-virtual-net-br0.device After=sys-devices-virtual-net-br0.device
A custom target can be created that will run at the end when all other services have completed. This is useful to ensure that running a program is the last thing that is performed as part of the boot up process.
Let's assume that the target name will be "microscope" that will have to run after the multi-user target has been reached, and by reaching the microscrope target, several programs will have to be started in the background.
First, the target is defined by creating a target file at /etc/systemd/system/microscope.target with the following contents:
[Unit] Description=Microscope Target Requires=multi-user.target After=multi-user.target AllowIsolate=yes
Now, the "microscope" target might want some service files to run when it is reached, such that the folder /etc/systemd/system/microscope.target.wants is created. Any service file that needs to run programs has to be linked into the /etc/systemd/system/microscope.target.wants folder. For example, let's create a service file at /etc/systemd/system/microscope.service with the following contents:
[Unit] Description=Microscope After=microscope_clone.service Before=microscope_button.service [Service] ExecStart=/usr/bin/ffmpeg -hide_banner -loglevel quiet -f v4l2 -video_size 640x420 -i /dev/video50 -pix_fmt rgb565le -f fbdev /dev/fb0 Restart=always RestartSec=10 StandardOutput=syslog StandardError=syslog SyslogIdentifier=microscope User=root Group=root Environment=PATH=/usr/bin/:/usr/local/bin/ [Install] WantedBy=microscope.target
The service file starts ffmpeg with some parameters and depends on two different service files microscope_clone.service and microscope_button.service. All the files are now linked into the wants of the microscope target:
ln -sf /etc/systemd/system/{microscope_clone,microscope,microscope_button}.service /etc/systemd/system/microscope.target.wants/
To make sure the changes are picked up, SystemD will be reloaded:
systemctl daemon-reload
Finally, the final target can be re-mapped from the default multi-user target to the new microscope target:
systemctl set-default microscope.target
The machine can be now either be rebooted or the changes can be applied immediately by issuing:
systemctl isolate microscope.target
The following configuration:
[Unit] StartLimitIntervalSec=0 [Service] RestartSec=10
when added to a service file, will have the effect of attempting to start the service successfully indefinitely by attempting a start the service every 10 seconds until it succeeds.
One of the cool thing that one could do would be to specify alternative directories to hold service files that are meant for groups of services pertaining to projects. Currently, the location to place service files using SystemD is /etc/systemd/system/ but that directory contains a lot of Linux' kitchen, with some of the files and links being managed by Linux setup scripts, such that adding files there does not feel too proper.
The solution is to specify an additional service file path at boot time. In order to do this, create the directory path /etc/systemd/system.conf.d/ and the file /etc/systemd/system.conf.d/systemd.conf with the following contents:
[Manager] ManagerEnvironment="SYSTEMD_UNIT_PATH=/mnt/docker/services:"
where:
/mnt/docker/services is the path to a directory containing the desired SystemD service files
Note that the colon at the end : will tell SystemD to append this path instead of substituting the system path with the user-specified path, which is exactly what was desired.
After a system reboot, service or unit files ca be placed in, following the example, the directory /mnt/docker/services and then loaded using the systemctl command. This achieves a very nice separation of concerns between the system managed service files, custom service files meant for projects, as well as user service files.