Kasheftin
Kasheftin

Reputation: 9493

npm does not run when called through nginx/php-fpm exec

I have a strange issue in my autodeploy script.

Basically that's the php script, that, when triggered through http, runs the other shell script with several commands like npm install and npm run build. This all works except the case when php script called from http nginx/php-fpm - this case npm command does not run.

I created the simple example repo to demonstrate the issue: https://github.com/Kasheftin/npm-bug

We have test.php that just runs test.sh shell command:

<?php
  exec("/home/www/tests/npm-bug/test.sh > /home/www/tests/npm-bug/test.log");

We have test.sh that just runs npm run test command:

#!/bin/bash
cd /home/www/tests/npm-bug
npm run test

Finally we have package.json with the following command:

"scripts": {
  "test": "echo \"Hello World!\""
}

The result of npm run test looks like:

> [email protected] test /home/www/tests/npm-bug
> echo "Hello World!"

Hello World!

Notice the last row - that's the result of the echo command in package.json. The same result appears in the case of ./test.sh command. And the same we get in test.log after running php test.php command.

But when I trigger test.php from http, I get only

> [email protected] test /home/www/tests/npm-bug
> echo "Hello World!"

Notice, that the last string is absent, npm command did not run.

Also I have this location rule in my nginx:

location = /npm-test {
  root /home/www/tests/npm-bug;
  rewrite ^(.*)$ /test.php break;
  include snippets/fastcgi-php.conf;
  fastcgi_pass unix:/run/php/php7.0-fpm.sock;
}

This all seems to be very standart, nginx and php7.0-fpm are right out of the box, the php config is just the same for cli and for fpm. Checked on two servers with different environment.

Upvotes: 2

Views: 1642

Answers (1)

Tarun Lalwani
Tarun Lalwani

Reputation: 146620

It was a interesting issue to solve. So the thing is that when you use

  exec("/home/www/tests/npm-bug/test.sh > /home/www/tests/npm-bug/test.log");

It mask all errors. You should actually do it like

  exec("/home/www/tests/npm-bug/test.sh > /home/www/tests/npm-bug/test.log 2>&1");

And now you will see a big error

npm ERR! Linux 4.4.0-66-generic
npm ERR! argv "/usr/bin/nodejs" "/usr/bin/npm" "run" "test"
npm ERR! node v4.2.6
npm ERR! npm  v3.5.2
npm ERR! file sh
npm ERR! path sh
npm ERR! code ELIFECYCLE
npm ERR! errno ENOENT
npm ERR! syscall spawn sh
npm ERR! [email protected] test: `sh -c 'echo "Hello World!"'`
npm ERR! spawn sh ENOENT
npm ERR!
npm ERR! Failed at the [email protected] test script 'sh -c 'echo "Hello World!"''.
npm ERR! Make sure you have the latest version of node.js and npm installed.

It took me sometime to figure out why. So I added the env statement to the shell file

USER=vagrant
PWD=/var/www/html/npm-bug
SHLVL=1
HOME=/home/vagrant
OLDPWD=/home/vagrant/nginx/html/npm-bug
_=/usr/bin/env

As you can see there in no PATH variable defined. This was the issue. I added the path variable in the shell script

export PATH=......

I took the path that my terminal showed on echo $PATH, and now it works from fpm also

Upvotes: 2

Related Questions