Getting the daemon working on NixOS

I recently decided to try out the new atuin daemon since I have been having some trouble with timeouts on zfs.

atuin daemon works fine when launched from the console, however, I’ve been struggling to get it to work as a systemd service. I’ve never set one up before so there’s a good chance I’m getting a few things wrong.

I set up the service with the following NixOS configuration:

systemd.services.atuin = {
  enable = true;

  environment = {
    HOME = "/home/ethan";
    ATUIN_LOG = "info";
  };
  serviceConfig = {
    ExecStart = "${pkgs.atuin}/bin/atuin daemon";
  };
  wantedBy = [ "multi-user.target" ];
  wants = [ "network.target" ];
};

And this atuin/config.toml:

[daemon]
enabled = true
socket_path = "/home/ethan/.local/share/atuin/atuin.sock"

The service starts successfully:

● atuin.service
     Loaded: loaded (/etc/systemd/system/atuin.service; enabled; preset: enabled)
     Active: active (running) since Thu 2024-05-23 22:10:17 BST; 13min ago
   Main PID: 343103 (atuin)
         IP: 19.1K in, 4.0K out
         IO: 0B read, 0B written
      Tasks: 4 (limit: 38415)
     Memory: 8.2M (peak: 8.9M)
        CPU: 89ms
     CGroup: /system.slice/atuin.service
             └─343103 /nix/store/h29ks5ll84qrc8pr56adk4k6xhb96mi7-atuin/bin/atuin daemon

May 23 22:10:17 nixos-desktop systemd[1]: Started atuin.service.
May 23 22:10:17 nixos-desktop atuin[343103]: 2024-05-23T21:10:17.038017Z  INFO atuin_daemon::server: listening on unix socket "/home/ethan/.local/share/atuin/atuin.sock"
May 23 22:10:17 nixos-desktop atuin[343103]: 2024-05-23T21:10:17.038084Z  INFO atuin_daemon::server::sync: booting sync worker
May 23 22:10:17 nixos-desktop atuin[343103]: 2024-05-23T21:10:17.039188Z  INFO atuin_daemon::server::sync: sync worker tick
May 23 22:10:17 nixos-desktop atuin[343103]: 2024-05-23T21:10:17.191047Z  INFO atuin_daemon::server::sync: sync complete uploaded=0 downloaded=[]

However I’m still getting errors after every command:

Error: failed to connect to local atuin daemon. Is it running?

Location:
    /build/source/crates/atuin-daemon/src/client.rs:31:26

Is there something I’m configuring incorrectly?

1 Like

You’re starting the daemon as a system service; you want it as a user service under your userid. The client failure will be file permissions on the socket.

3 Likes

Oh I see. Thanks that helped.

One other thing I was missing was that I needed to run systemctl status with --user.

In case anyone finds this post with the same struggle, here’s the working configuration I ended up with.

systemd.user.services.atuind = {
  enable = true;

  environment = {
    ATUIN_LOG = "info";
  };
  serviceConfig = {
    ExecStart = "${pkgs.atuin}/bin/atuin daemon";
  };
  after = [ "network.target" ];
  wantedBy = [ "default.target" ];
};
7 Likes

Is it possible to add this service in your home-manager config? I saw an option for home-manager to add a user service, but if I use this option to create this service the daemon won’t start.

This is what I use with h-m:


  systemd.user =
    let
      atuinSockDir = "${config.home.homeDirectory}/.local/share/atuin";
      atuinSock = "${atuinSockDir}/atuin.sock";
      unitConfig = {
        Description = "Atuin Magical Shell History Daemon";
        ConditionPathIsDirectory = atuinSockDir;
        ConditionPathExists = "${config.home.homeDirectory}/.config/atuin/config.toml";
      };
    in
    {
      sockets.atuin-daemon = {
        Unit = unitConfig;
        Install.WantedBy = [ "default.target" ];
        Socket = {
          ListenStream = atuinSock;
          Accept = false;
          SocketMode = "0600";
        };
      };
      services.atuin-daemon = {
        Unit = unitConfig;
        Service.ExecStart = "${pkgs.atuin}/bin/atuin daemon";
      };
    };

Along with the following as part of atuin setup, to use socket activation:


    programs.atuin = {
      enable = true;
      settings = {
        # …
        daemon.enabled = true;
        daemon.systemd_socket = true;
       };
    };
2 Likes

This looks great. I will have to give it a try. Maybe we could even package it for h-m for Atuin, I think. That would make it easier to enable the daemon for everyone.

Yeah I was going to add it to hm once the feature moves out of the “experimental” status; last I knew it was still not intended to be widely used, mostly in case some incompatible change needs to be made. If it has been stabilised since, I missed it.

3 Likes

I think it’s been used by enough people now that we can trust it to be stable. I’ll look at moving it to be better supported in the next release

3 Likes

Sounds great. We could even add the hm option already with a note saying that the daemon support is experimental or something similar. Personally, I do not think there would be a problem with that.

1 Like

For future reference:
Atuin 18.4.0 introduced a change to the default location of a socket for the daemon.
It uses the socket /run/user/1000/atuin.sock, if XDG_RUNTIME_DIR is set. Relevant PR:

Without home-manager

Use the above-shown manual service and socket configuration. Ideally, set the socket directory to what Atuin should default to:

-      atuinSockDir = "${config.home.homeDirectory}/.local/share/atuin";
+      atuinSockDir = "%t";

See section Context for additional explanation. If you have problems with the daemon timing out, set timeout times in the Atuin config, e.g. as in section With home-manager,

With home-manager

The daemon on NixOS with Atuin 18.4.0 from the nixpkgs with the home-manager module for Atuin and its daemon works correctly now.

The configuration of the home-manager module for Atuin for the daemon is as follows. (Only, I have a strange issue with connectivity where it takes around 8–15 seconds to connect to the server, which by default times out on a timeout of 5 seconds, so I had to modify the Atuin config accordingly (either as a Nix expression, or an imported TOML value) in the module attribute settings.

# Might not be necessary for you.
network_connect_timeout = 60
network_timeout = 60

[daemon]
enabled = true
systemd_socket = true

Notice that we do not define systemd_path, allowing the home-manager to use the new default of ${XDG_RUNTIME_DIR}/atuin.sock if it is set.

With the h-m configuration:

  programs.atuin = {
    enable = true;
    enableBashIntegration = true;
    enableFishIntegration = true;
    enableZshIntegration = true;
    daemon = {
      enable = true;
    };
    settings = lib.importTOML atuin_config_file.toml;
  };

Context

The previous default location (~/.local/share/atuin/atuin.sock) will not work with h-m as it hardcodes the path for Atuin version 18.4.0+ to %t/atuin.sock which is defined as follows:

The %t specifier in systemd service files represents the runtime directory. It is either /run for the root user or the value of the XDG_RUNTIME_DIR variable for unprivileged users.

1 Like

Yes, I opened https://github.com/atuinsh/atuin/issues/2525 two days ago… :sweat_smile: (sorry, I’m not allowed to post the link)