Run the engine as a service
A user service under systemd. Nothing about the engine needs root.
The wizard does this for you. This page is what it does, for when you would rather do it yourself.
The engine needs no privilege beyond reading your data and writing its own directory, so run it as an ordinary user, from that user’s own units.
# ~/.config/systemd/user/nils-engine.service
[Unit]
Description=NILS engine
After=network-online.target
[Service]
ExecStart=/usr/local/bin/nils serve \
--bind 127.0.0.1:8437 \
--registry %h/nils/registry \
--pack-dir %h/nils/packs \
--backup-dir %h/nils/backups \
--worker
Restart=on-failure
[Install]
WantedBy=default.target
systemctl --user daemon-reload
systemctl --user enable --now nils-engine
systemctl --user status nils-engine
So that it runs when nobody is logged in:
loginctl enable-linger $USER
Its output goes to the journal:
journalctl --user -u nils-engine -f
A machine that serves a group
Make a user for it rather than running it as a person:
sudo useradd --system --create-home --home-dir /srv/nils --shell /usr/sbin/nologin nils
sudo loginctl enable-linger nils
sudo -u nils XDG_RUNTIME_DIR=/run/user/$(id -u nils) systemctl --user enable --now nils-engine
The same unit file, in that user’s ~/.config/systemd/user/. Keep the registry, the packs and the backups under its home, owned by it.
Updating
Replace the binary and restart:
sudo install -m 755 nils /usr/local/bin/nils
systemctl --user restart nils-engine
The engine migrates its own registry when the schema moved, and refuses to start against a registry newer than itself rather than damaging it. Take a backup first (nils backup) if the jump is more than a patch.
Next: in a container.
Updated 13 September 2026