user11810894
user11810894

Reputation:

How to install systemd service on nixos

If I do this:

#!/usr/bin/env bash

set -e;

cd "$(dirname "$BASH_SOURCE")"

ln -sf "$(pwd)/interos-es-mdb.service" '/etc/systemd/system/interos-es-mdb.service'

systemctl enable interos-es-mdb.service
systemctl start interos-es-mdb.service

then I get this error:

ln: failed to create symbolic link '/etc/systemd/system/interos-es-mdb.service': Read-only file system

anyone know the right way to install a service on nixos machine? (I am the root user)...here is the service for reference:

[Unit]
Description=Interos MongoDB+ES log capture
After=network.target

[Service]
Environment=interos_emit_only_json=yes
EnvironmentFile=/root/interos/env/es-service.env
StartLimitIntervalSec=0
Type=simple
Restart=always
RestartSec=1
ExecStart=/root/interos/repos/elastic-search-app/syslog-exec.sh

[Install]
WantedBy=multi-user.target

update: perhaps what I am looking for is "per-user" service, not something run as root etcetera.

Upvotes: 8

Views: 26710

Answers (2)

nrdxp
nrdxp

Reputation: 802

The reason its broken

NixOS is a declarative operating system. This means that directories like /etc live inside the read-only /nix/store directory. Only the nix-daemon is allowed to mount the nix-store as writable. Therefore, you must create a systemd.services.<yourservice> entry in your configuration.nix to interact with the underlying system; alternatively you can patch nixpkgs directly and point your configuration to your fork.

All running services not declared explicitly by the user can be assumed to live inside nixpkgs/nixos/modules.

Fix

configuration.nix:

{
  systemd.services.foo = {
    enable = true;
    description = "bar";
    unitConfig = {
      Type = "simple";
      # ...
    };
    serviceConfig = {
      ExecStart = "${foo}/bin/foo";
      # ...
    };
    wantedBy = [ "multi-user.target" ];
    # ...
  };
}

user services

almost identical except they begin with systemd.user.services. In addition, user home directories are not managed declartively, so you can also place a regular systemd unit file under $XDG_CONFIG_DIR/systemd as usual.

relevant:

Full list of valid attributes for systemd.services.<name>, From: NixOS Manual

Module basics, From: Wiki

Upvotes: 19

Charles Duffy
Charles Duffy

Reputation: 295510

An appropriate entry in your /etc/nixos/configuration.nix might look like:

let
  # assumes you build a derivation for your software and put it in
  # /etc/nixos/pkgs/interosEsMdb/default.nix
  interosEsMdb = import ./pkgs/interosEsMdb {};
in config.systemd.services.interosEsMdb = {
  description = "Interos MongoDB+ES log capture";
  after = ["network.target"];
  wantedBy = ["multi-user.target"];

  serviceConfig = {
    # change this to refer to your actual derivation
    ExecStart = "${interosEsMdb}/bin/syslog-exec.sh";
    EnvironmentFile = "${interosEsMdb}/lib/es-service.env";
    Restart = "always";
    RestartSec = 1;
  }
}

...assuming you actually build a derivation for interosEsMdb (which is the only sane and proper way to package software on NixOS).

Upvotes: 1

Related Questions