Custom SystemD units¶
You can define your own unit files using NixOS configuration modules
in /etc/local/nixos
or plain unit files in /etc/local/systemd
.
Using NixOS configuration is the most flexible approach.
Plain unit files are more limited and may not work as expected.
A few notes that you should pay attention to:
We do not enforce the user. You can start your services as root, but that may easily cause permission issues and poses severe security risk. Please confine your services to an appropriate user, typically your service user.
Your service should not daemonize / detach on its own. SystemD works best when you just start and stay attached in the foreground.
See the systemd.service and related manpages for further information.
NixOS Configuration¶
By writing a custom NixOS module, you can define all kinds of SystemD units.
See the NixOS options for service units for all available settings.
Timer Example¶
Place the following NixOS module in /etc/local/nixos/systemd-mytask.nix
:
{ config, pkgs, ... }:
{
systemd.timers.mytask = {
wantedBy = [ "timers.target" ];
timerConfig = {
OnCalendar = "daily";
Persistent = true;
};
};
systemd.services.mytask = {
path = with pkgs; [
bash # adds all binaries from the bash package to PATH
"/run/wrappers" # if you need something from /run/wrappers/bin, sudo, for example
];
serviceConfig = {
Description = "Run daily maintenance script.";
Type = "oneshot";
User = "test";
ExecStart = "/srv/test/mytask.sh";
# Set environment variables for the script.
Environment = [
"LD_LIBRARY_PATH=${pkgs.file}/lib"
"VERBOSE=1"
];
};
};
}
Plain SystemD units¶
You can still place plain unit config in in /etc/local/systemd/<unit-name>.service
but it’s deprecated on NixOS 19.03/20.09.
We bind your service unit to the multi-user.target
by default so they
will be automatically started upon boot and stopped properly when the
machine shuts down.
Warning
Don’t use this for services that are meant to be started by a timer! Oneshot services defined this way are triggered on by our management task which means that they will run every 10 minutes!
A simple unit file to start a service may look like this:
[Unit]
Description=My Application Service
[Service]
Environment="PATH=/run/wrappers/bin:/nix/var/nix/profiles/default/bin:/nix/var/nix/profiles/default/sbin:/run/current-system/sw/bin:/run/current-system/sw/sbin"
User=s-myservice
Group=service
ExecStart=/srv/s-myservice/bin/runme