- Notifications
You must be signed in to change notification settings - Fork 0
Services
System and user services configuration in NullOS.
NullOS configures services at two levels:
- System services - NixOS configuration (require sudo)
- User services - Home Manager (run as user)
Configured in modules/services/ directory.
Pipewire (modules/services/audio.nix):
services.pipewire={enable=true;alsa.enable=true;alsa.support32Bit=true;pulse.enable=true;jack.enable=true;wireplumber.enable=true;};hardware.pulseaudio.enable=false;Features:
- Low-latency audio
- ALSA compatibility
- PulseAudio replacement
- JACK support
- Bluetooth audio
Control:
# Volume control
wpctl set-volume @DEFAULT_AUDIO_SINK@ 5%+
wpctl set-volume @DEFAULT_AUDIO_SINK@ 5%-
wpctl set-mute @DEFAULT_AUDIO_SINK@ toggle
# List devices
wpctl statusSDDM (modules/services/sddm.nix):
services.displayManager.sddm={enable=true;wayland.enable=true;theme="sugar-candy";package=pkgs.kdePackages.sddm;};Auto-login:
services.displayManager.autoLogin={enable=vars.autoLogin;user=vars.username;};XDG Desktop Portal (modules/services/xdg-portal.nix):
xdg.portal={enable=true;extraPortals=withpkgs;[xdg-desktop-portal-gtkxdg-desktop-portal-hyprland];config.common.default="*";};Provides:
- Screen sharing
- File picker
- Notifications
- Screenshot portal
NetworkManager:
networking.networkmanager.enable=true;users.users.${vars.username}.extraGroups=["networkmanager"];Control:
# CLI
nmcli device wifi list
nmcli device wifi connect SSID password PASSWORD
# GUI
nm-applet # System trayBlueZ:
hardware.bluetooth={enable=true;powerOnBoot=true;settings={General={Enable="Source,Sink,Media,Socket";Experimental=true;};};};services.blueman.enable=true;Control:
# CLI
bluetoothctl
> scan on
> pair XX:XX:XX:XX:XX:XX
> connect XX:XX:XX:XX:XX:XX
# GUI
blueman-managerCUPS:
services.printing={enable=true;drivers=withpkgs;[gutenprinthplipsplix];};services.avahi={enable=true;nssmdns4=true;openFirewall=true;};Manage:
# Web interface
http://localhost:631/
# CLI
lpstat -p -d
lpr -P printer-name file.pdfDocker (modules/services/virtualisation.nix):
virtualisation.docker={enable=true;enableOnBoot=true;daemon.settings={data-root="/var/lib/docker";};};users.users.${vars.username}.extraGroups=["docker"];Libvirt (optional):
virtualisation.libvirtd={enable=true;qemu={package=pkgs.qemu_kvm;ovmf.enable=true;swtpm.enable=true;};};users.users.${vars.username}.extraGroups=["libvirtd"];services.openssh={enable=true;settings={PermitRootLogin="no";PasswordAuthentication=false;};ports=[22];};Firewall:
networking.firewall.allowedTCPPorts=[22];plocate:
services.locate={enable=true;package=pkgs.plocate;localuser=null;};Usage:
# Update database
sudo updatedb
# Search
locate filenameservices.flatpak.enable=true;xdg.portal.enable=true;Usage:
# Add Flathub
flatpak remote-add --if-not-exists flathub https://flathub.org/repo/flathub.flatpakrepo
# Install
flatpak install flathub org.gimp.GIMP
# Run
flatpak run org.gimp.GIMPsystem.autoUpgrade={enable=false;# Manual recommendedflake="/home/${vars.username}/NullOS";dates="weekly";allowReboot=false;};nix.gc={automatic=true;dates="weekly";options="--delete-older-than 30d";};nix.optimise={automatic=true;dates=["weekly"];};Configured via Home Manager in home/ directory.
Wallpaper Service:
systemd.user.services.hyprpaper={Unit={Description="Hyprland wallpaper daemon";PartOf=["graphical-session.target"];After=["graphical-session.target"];};Service={ExecStart="${pkgs.hyprpaper}/bin/hyprpaper";Restart="on-failure";};Install={WantedBy=["hyprland-session.target"];};};Notification Daemon (home/swaync.nix):
services.swaync={enable=true;settings={positionX="right";positionY="top";control-center-width=380;notification-visibility={telegram={state="muted";};};};};On-Screen Display (home/swayosd.nix):
services.swayosd={enable=true;topMargin=0.9;};Shows OSD for:
- Volume changes
- Brightness changes
- Caps Lock
services.syncthing={enable=true;user=vars.username;dataDir="/home/${vars.username}/.syncthing";configDir="/home/${vars.username}/.config/syncthing";overrideDevices=true;overrideFolders=true;settings={devices={"device1"={id="DEVICE-ID-HERE";};};folders={"Documents"={path="/home/${vars.username}/Documents";devices=["device1"];};};};};Backup services are typically configured at the system level using Restic.
See Backup for complete configuration.
Music Player Daemon:
services.mpd={enable=true;musicDirectory="/home/${vars.username}/Music";extraConfig='' audio_output { type "pipewire" name "PipeWire" } '';};services.mpdris2.enable=true;# MPRIS supportText Expander:
services.espanso={enable=true;configs={default={toggle_key="CTRL";};};matches={base={matches=[{trigger=":shrug";replace="¯\\_(ツ)_/¯";}];};};};Check status:
sudo systemctl status service-nameStart/Stop:
sudo systemctl start service-name
sudo systemctl stop service-name
sudo systemctl restart service-nameEnable/Disable:
sudo systemctl enable service-name
sudo systemctl disable service-nameView logs:
sudo journalctl -u service-name
sudo journalctl -u service-name -f # FollowCheck status:
systemctl --user status service-nameStart/Stop:
systemctl --user start service-name
systemctl --user stop service-name
systemctl --user restart service-nameEnable/Disable:
systemctl --user enable service-name
systemctl --user disable service-nameView logs:
journalctl --user -u service-name
journalctl --user -u service-name -fAll system services:
systemctl list-units --type=serviceAll user services:
systemctl --user list-units --type=serviceFailed services:
systemctl list-units --failed
systemctl --user list-units --failedCreate modules/services/my-service.nix:
{config,pkgs,vars, ... }:
{systemd.services.my-service={description="My Custom Service";wantedBy=["multi-user.target"];after=["network.target"];serviceConfig={Type="simple";ExecStart="${pkgs.my-package}/bin/my-command";Restart="on-failure";RestartSec="5s";User=vars.username;Group="users";# SecurityPrivateTmp=true;NoNewPrivileges=true;ProtectSystem="strict";ProtectHome=true;};};}Import in configuration.nix or modules/services/default.nix.
In home/my-service.nix:
{config,pkgs, ... }:
{systemd.user.services.my-service={Unit={Description="My User Service";After=["graphical-session.target"];};Service={ExecStart="${pkgs.my-package}/bin/my-command";Restart="on-failure";RestartSec="5s";};Install={WantedBy=["default.target"];};};}System timer:
systemd.timers.my-timer={wantedBy=["timers.target"];timerConfig={OnCalendar="daily";OnBootSec="5m";Persistent=true;};};systemd.services.my-timer={serviceConfig={Type="oneshot";ExecStart="${pkgs.bash}/bin/bash -c 'echo hello'";};};User timer:
systemd.user.timers.my-timer={Unit={Description="My Timer";};Timer={OnCalendar="hourly";Persistent=true;};Install={WantedBy=["timers.target"];};};systemd.services.my-service={after=["network.target""other-service.service"];before=["another-service.service"];requires=["required-service.service"];wants=["optional-service.service"];};Difference:
requires- Hard dependency (fails if missing)wants- Soft dependency (continues if missing)after- Start after other servicebefore- Start before other service
serviceConfig={# ProcessUser="specific-user";Group="specific-group";NoNewPrivileges=true;# FilesystemPrivateTmp=true;ProtectSystem="strict";ProtectHome=true;ReadWritePaths=["/var/lib/myservice"];# NetworkPrivateNetwork=false;RestrictAddressFamilies=["AF_INET""AF_INET6"];# CapabilitiesCapabilityBoundingSet=["CAP_NET_BIND_SERVICE"];AmbientCapabilities=["CAP_NET_BIND_SERVICE"];# System callsSystemCallFilter="@system-service";SystemCallErrorNumber="EPERM";};systemd-analyze security service-namesystemd.services.my-service={environment={MY_VAR="value";PATH="${pkgs.package}/bin";};# Or from fileenvironmentFile="/run/secrets/service-env";};systemd.user.services.my-service={Service={Environment="MY_VAR=value";EnvironmentFile="/home/user/.env";};};# Check status
systemctl status service-name
# View full logs
journalctl -u service-name -n 100
# Check for errors
journalctl -p err -u service-name# Check restart count
systemctl show service-name -p NRestarts
# Increase verbosity
journalctl -u service-name -f --output=verbose# Check which user runs service
systemctl show service-name -p User
# Check file permissions
ls -l /path/to/file
# Test command manually
sudo -u username /path/to/command- Use Security Options - Restrict what services can access
- Set Restart Policies - Handle crashes gracefully
- Log Appropriately - Use structured logging
- Resource Limits - Prevent resource exhaustion
- User Services When Possible - Don't run as root unnecessarily
- Specialisations - Alternative boot configurations
- System Applications - System packages
- Troubleshooting - Debugging issues
- Backup - Backup service configuration