Why does my systemd service fails only inside systemd and not outside of it

So there’s this program mpdas which I try to run in a systemd service. Here’s the service:

    systemd.services.mpdas = {
      description = "Music Player Daemon Scrobbler (mpdas)";
      bindsTo = ["mpd.service"];
      wantedBy = [ "multi-user.target" ];
      unitConfig = { RequiresMountsFor = "/var/lib/mpd"; };
      serviceConfig = {
        # That file's format is configured here:
        # https://github.com/hrkfdn/mpdas/tree/master#configuration
        ExecStart = "${pkgs.mpdas}/bin/mpdas";
        # A little bit more complicated then mpd's prestart script because it
        # has to parse the mpd conf file format
        ExecStartPre = pkgs.writeScript "mpdas-start-pre" ''
          #!${pkgs.runtimeShell}
          set -euo pipefail
          password=$(${pkgs.gawk}/bin/awk -F'[@"]' '$1 == "password " {print $2}' /var/lib/secrets/mpd.conf)
          echo "mpdpassword = $password" > /etc/mpdasrc
          cat /var/lib/secrets/mpdas.conf >> /etc/mpdasrc
        '';
        Type = "simple";
      };
    };

And it fails with:

May 16 10:35:59 NUX mpdas[825]: terminate called after throwing an instance of 'std::logic_error'
May 16 10:35:59 NUX mpdas[825]:   what():  basic_string::_M_construct null not valid

While sudo /nix/store/i58ym4xm7v34c4l7gawg3w8frgrvk75y-mpdas-0.4.5/bin/mpdas doesn’t fail :confused: . Don’t know why.

I had a brief look at https://github.com/hrkfdn/mpdas/blob/c81c480a6081af104c70c3574fb71319ff1521b7/main.cpp and it appears to read environment variables via getenv().

Would you mind trying setting the HOME env variable (via systemd.services.mpdas.environment.HOME = … ) or something along those lines?

It worked! I’ll talk with upstream about this. Thanks!

Unless you’re running this on a dedicated device (like a rpi connected to a speaker setup), you really shouldn’t be running mpd/mpdas as root but instead through a systemd user instance as yourself.

Hmm right… And what if I set:

[Service]
User=mpd

This should be a bit better right? mpd it self is running that way.

[Service]
User=mpd

This should be a bit better right?

Sure, that’s better than root, but a music player really shouldn’t be a system-level service.

mpd it self is running that way.

Just because you can, doesn’t mean you should. The right way to do this is in a user session. You wouldn’t say “I will only support a single firefox instance on this entire machine” either, so a music player really isn’t any different (except for the dedicated device usecase).

Check out home-manager if you haven’t already as it has support for this but it’s entirely doable in straight nixos too.