Search code examples
perlsystemddancerperlbrew

systemd service for a perlbrew application?


My coworker wrote a Dancer psgi application called "Newlands" that makes use of perlbrew. I am trying to get the application to start up on system start using systemd. I have this service file:

[Unit]
Description=Newlands
After=network-online.target

[Service]
Type=forking
User=newlands
WorkingDirectory=/home/newlands/working/newlands
PIDFile=/home/newlands/newlands.pid
ExecStartPre=/bin/bash -c 'env > /tmp/newlands.environment'
ExecStartPre=/bin/mkdir -p /tmp/newlands/newlands/session/
ExecStart=/usr/local/bin/starman --host 127.0.0.1 --listen :5000 --env production --preload-app --workers 12 --daemonize --error-log /var/log/newlands/newlands.error.log --pid /home/newlands/newlands.pid bin/newlandia.psgi
EnvironmentFile=-/tmp/newlands.environment
Restart=always

[Install]
WantedBy=multi-user.target

However, even with the ExecStartPre trick (which I got from http://tech.akom.net/archives/93-Getting-a-systemd-unit-to-read-your-.bashrc-file-for-its-environment.html, modified not use the --login option), none of the perlbrew-related environment variables are getting set properly. So I end up with errors indicating missing libraries not found in @INC, when @INC doesn't contain anything at /home/newlands/.perlbrew/libs/perl-5.20.1@newlands where the libraries actually are.

It seems that the outputted file at /tmp/newlands.environment still differs significantly from the output of "env" when actually logged in as the newlands user. I would like to source /opt/perlbrew/etc/bashrc or something like that, but I understand that's not possible.

Any tips? Thanks!


Solution

  • The solution is not to blindly dump your Bash CLI environment into your systemd environment, the solution is to understand what environment variables you need and set those.

    As @ikegami points out, your problem is likely related to the PERL5LIB environment variable. So run your app from the CLI from and dump out the value of $ENV{PERL5LIB} to see what value the app expects, then set that in systemd. You may need to repeat the process with other variables.

    The result will be a clearly and precisely defined systemd environment that will run your app in a stable and consistent manner, regardless of how your .bashrc gets modified.