Reputation:
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
Reputation: 802
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
.
configuration.nix:
{
systemd.services.foo = {
enable = true;
description = "bar";
unitConfig = {
Type = "simple";
# ...
};
serviceConfig = {
ExecStart = "${foo}/bin/foo";
# ...
};
wantedBy = [ "multi-user.target" ];
# ...
};
}
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.
Full list of valid attributes for systemd.services.<name>
, From: NixOS Manual
Module basics, From: Wiki
Upvotes: 19
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