3

I am trying to use a systemd service to run a Node app (specifically, a React app generated with create-react-app. I put a file frontend.service at /etc/systemd/system/ with (minimally) these contents:

[Unit]
Description=React Web Application

[Service]
ExecStart=/usr/local/bin/npm start --prefix=<path to app>

[Install]
WantedBy=multi-user.target

After starting the service, my browser shows the nginx bad gateway error, and ps aux | grep node shows no corresponding process. The output of journalctl -u frontend reports successful steps like "Started React Web Application" and eventually "Starting development server...". However, systemctl status frontend reports that the service is loaded but inactive/dead (edit: or, active/exited).

I tried some adjustments to the .service file, in particular Type=forking, RemainAfterExit=true, and KillMode=process. But the problem persists. What is going on? How to fix this?

The app does work fine if I run it directly using npm start in the shell. Also, another (non-node) web server works fine running through a similar systemd script.

Here is the systemctl status output:

wm-frontend.service - React Web Application
   Loaded: loaded (/etc/systemd/system/wm-frontend.service; enabled; vendor preset: enabled)
   Active: active (exited) since Mon 2020-08-10 14:40:59 UTC; 32min ago
  Process: 4033 ExecStart=/usr/local/bin/npm start --prefix=/home/mw/wm-ax/frontend/blog --scripts-prepend-node-path (code=exited, status=0/SUCCESS)
 Main PID: 4033 (code=exited, status=0/SUCCESS)

Aug 10 14:40:59 localhost systemd[1]: Started React Web Application.
Aug 10 14:41:00 localhost npm[4033]: > [email protected] start /home/mw/wm-ax/frontend/blog
Aug 10 14:41:00 localhost npm[4033]: > react-scripts start
Aug 10 14:41:04 localhost npm[4033]: ℹ 「wds」: Project is running at http://0.0.0.0:3000/
Aug 10 14:41:04 localhost npm[4033]: ℹ 「wds」: webpack output is served from
Aug 10 14:41:04 localhost npm[4033]: ℹ 「wds」: Content not from webpack is served from /home/mw/wm-ax/frontend/blog/public
Aug 10 14:41:04 localhost npm[4033]: ℹ 「wds」: 404s will fallback to /
Aug 10 14:41:04 localhost npm[4033]: Starting the development server...
13
  • When you run it by hand in the shell does it stay in the foreground? Aug 9, 2020 at 16:43
  • Yes, npm start leaves a process running in the foreground.
    – mmw
    Aug 9, 2020 at 18:12
  • One possible explanation might be that npm start issues a fork at some point (could there be distinct build and serve processes?), and that systemd stops the child process once build returns.
    – mmw
    Aug 9, 2020 at 18:28
  • I'm thinking environment variable. What happens if you run env -i /usr/local/bin/npm start? If that has a problem, then figure out which environment variable your application needs and set it in your service file.
    – Stewart
    Aug 10, 2020 at 8:54
  • Interesting thought! When prefixed by env -i, the npm start command fails, with ~/.npm/_log file suggesting the flag --scripts-prepend-node-path. This flag does allow npm start to run from an empty environment. However, the result of adding the flag to the ExecStart entry of the systemd script still doesn't work:(.
    – mmw
    Aug 10, 2020 at 14:59

1 Answer 1

3

As stated in this answer, as of February 2020 the start.js process is stipulated to exit when it reaches the end of stdin. When the process is run non-interactively (as by a systemd service), the end of stdin is immediate, and so the script terminates as described above.

2
  • Curious, was there an argument you had to pass to make IsInteractive false? Or did you have to set StandardInput=?
    – Stewart
    Aug 16, 2020 at 8:58
  • In the start.js script, that constant is set using the Node process api, with const isInteractive = process.stdout.isTTY.
    – mmw
    Aug 19, 2020 at 11:35

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .