0

I would like to know how to run a service described, like in a module on a non-Nix OS. For example let us say I have the file:

{config, pkgs, ... }:
{
  systemd.user.services.mytestservice = {
    description = "Mytestservice";
    script = "while true; do echo 'YES'; sleep 1; done";
    wantedBy = [ "default.target" ];
 };
}

(or eventually without the user: systemd.services.mytestservice =)

How can I compile it and run it on non-nixos OS, eventually by non-root users?

  • This question need to be made clearer, if you expect a quality response. – ctrl-alt-delor Oct 3 at 19:49
1
+50

Acknowledgment: Thanks a lot to clever for all the explanations!

Let us first write the configuration file in myconfiguration.nix:

{config, pkgs, ... }:

{
  # You can actually remove the user, and still use it
  # as a user if you link it in ~/.config/systemd/user/
  # (do not forget to remove the `user` it in anything.nix
  # as well)
  systemd.user.services.mytestservice = {
   description = "Mytestservice";
   script = "while true; do echo 'YES'; sleep 1; done";
   # Or:
   # serviceConfig = {
   #   ExecStart = "${pkgs.bash}/bin/bash -c \"while true; do echo 'YES'; sleep 1; done\"";
   # };
   wantedBy = [ "default.target" ];
 };
}

Then, you can de several things:

  • compile it
  • install it

To compile only, you can do:

nix-build '<nixpkgs/nixos>' -I nixos-config=myconfiguration.nix -A 'config.systemd.user.units."mytestservice.service".unit'

The idea is that this loads the file default.nix in the folder /your/nixpkgs/copy/nixos/ (to get the path of nixpkgs, it checks the variable NIX_PATH that contains several "subkeys" like : NIX_PATH=nixpkgs=/your/nixpkgs/copy/:othervar=thepath), which is available online here. This file requires also <nixos-config>, to we use -I to add a nixos-config entry to the NIX_PATH environment variable. Then without the -A, it will try to build a full nixos, so we just specify that we want only this service unit.

This will produce a file mytestservice.service that will look like that:

$ cat result/mytestservice.service 
[Unit]
Description=Mytestservice

[Service]
Environment="LOCALE_ARCHIVE=/nix/store/zzhablipzgpv8mvlcvagqjnham6lr944-glibc-locales-2.27/lib/locale/locale-archive"
Environment="PATH=/nix/store/bv1lw6a2kw0mn2y3lxhi43180idx6sp9-coreutils-8.31/bin:/nix/store/s1n4vl1f3in3nacalrc3xam0vyzpsfvs-findutils-4.6.0/bin:/nix/store/7d9bi31h40hky30f5scqx7r6wn311ain-gnugrep-3.3/bin:/nix/store/qg4qbkbca7qapfzpa8p991yjf944fc3w-gnused-4.7/bin:/nix/store/6bvd29jny80ka8df9prr5hrl5yz7d98k-systemd-239.20190219/bin:/nix/store/bv1lw6a2kw0mn2y3lxhi43180idx6sp9-coreutils-8.31/sbin:/nix/store/s1n4vl1f3in3nacalrc3xam0vyzpsfvs-findutils-4.6.0/sbin:/nix/store/7d9bi31h40hky30f5scqx7r6wn311ain-gnugrep-3.3/sbin:/nix/store/qg4qbkbca7qapfzpa8p991yjf944fc3w-gnused-4.7/sbin:/nix/store/6bvd29jny80ka8df9prr5hrl5yz7d98k-systemd-239.20190219/sbin"
Environment="TZDIR=/nix/store/20wmykp8fj2izxdj8lic8ggcfpdid5ka-tzdata-2019a/share/zoneinfo"



ExecStart=/nix/store/1f0wk7l4p7xv257dci8xxqz1k8nai9va-unit-script-mytestservice-start 

Now, if you want to be able to call it, you need to install it:

nix-env -f '<nixpkgs/nixos>' -I nixos-config=myconfiguration.nix -iA 'config.systemd.user.units."mytestservice.service".unit'

This will link the mytestservice.service into ~/.nix-profile/mytestservice.service. But systemctl expects it to be in ~/.config/systemd/user/, so we link it:

ln -s ~/.nix-profile/mytestservice.service ~/.config/systemd/user/

Then we need to reload the daemon, and we can try playing with it:

systemctl --user daemon-reload
systemctl --user start mytestservice.service

Note however that the build/install commands are complicated and long to type, so we can create a file, say anything.nix, that will build everything for us:

let
  eval = import <nixpkgs/nixos> {
    configuration = ./myconfiguration.nix;
  };
  pkgs = import <nixpkgs>{};
in pkgs.buildEnv {
  name = "things";
  paths = [
    eval.config.systemd.user.units."mytestservice.service".unit
  ];
}

Now, you can compile with:

nix-build anything.nix

and install with

nix-env -f anything.nix -i things

Note that you may need to remove the first time the file we installed with the other method, by using something like:

nix-env --query
nix-env --uninstall unit-mytestservice.service

Finally, both codes systemd.services and systemd.services.users seems to be usable with this method :D

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.