I have a systemd service that looks like this:
[Unit]
Description=Kcrypt Backend Webpack Bundler
After=network.target
[Service]
User=kenny
Environment=NODE_ENV=PROD
WorkingDirectory=/var/www/kcrypt-api/
ExecStart=/var/www/kcrypt-api/scripts/webpack.sh
[Install]
WantedBy=multi-user.target
The .sh file looks like this:
#!/usr/bin/env bash
export NODE_ENV=DEV
rm ./dist/* -rf
yarn start webpack --watch
The problem is that it cannot find yarn
.
My user is called kenny
. kenny
has a tool called nvm
installed that manages nodejs
versions. That tool adds a directory to the PATH
env variable by editing '~/.bashrc'.
That means that the yarn
command is only available if the user is logged in as kenny
.
I was left with the impression that if I set the systemd
's unit
's user to 'kenny', systemd
will take care of the rest, or I don't know what I was thinking.
Is there any way that I can import kenny
's PATH variable into the systemd
unit
?
Instead of trying to 'reference a user's
PATH
variable', you should either definePATH
manually, or more appropriately, use the full path to the binary.This isn't accurate. It just means that
yarn
isn't installed in a location referenced by thePATH
variable used by systemd, and is likely in a custom location, or location outside of the default PATH variable.When you're logged in as
kenny
, usewhich yarn
to print the path toyarn
, then make sure to use that when referencing it in the script.bash will only source
~/.bashrc
if you're running it as an interactive shell, it won't do that if you're simply running bash for a script.Considering systemd is only running bash as the interpreter of the
webpack.sh
script (in fact, it doesn't even know that bash is involved, the kernel executes it as the interpreter from the #! line), then it's not an interactive shell, and no startup files are read.You can work around that by sourcing
~/.bashrc
explicitly at the start of yourwebpack.sh
script, assuming everything in there is safe to run in a non-interactive shell. (It should be fine.)So consider adding this line to the start of your script: