Run `npx` from PHP app
The information in this post is accurate as of the published date . Please make sure to check any linked documentation within the post for changes/updates.
Hey
I need to execute some npx
commands from a PHP (Symfony) app.
I’m already following this guide to add node/nvm to my setup (and to build some assets at the build hook).
I tried running npx
commands but I get the following error: npx: not found
.
So I added this step to the build hook: npm install -g npx
but then got this error when building:
W: npm ERR! code EEXIST
W: npm ERR! syscall symlink
W: npm ERR! path ../lib/node_modules/npx/index.js
W: npm ERR! dest /app/.nvm/versions/node/v12.16.1/bin/npx
W: npm ERR! errno -17
W: npm ERR! EEXIST: file already exists, symlink '../lib/node_modules/npx/index.js' -> '/app/.nvm/versions/node/v12.16.1/bin/npx'
W: npm ERR! File exists: /app/.nvm/versions/node/v12.16.1/bin/npx
W: npm ERR! Remove the existing file and try again, or run npm
W: npm ERR! with --force to overwrite files recklessly.
W:
W: npm ERR! A complete log of this run can be found in:
W: npm ERR! /mnt/cache/npm/_logs/2020-10-13T07_36_03_432Z-debug.log
W: 0
E: Error building project: Step failed with status code 239.
``
E: Error: Unable to build application, aborting.
So it looks like npx
is already here, but I can’t seem to be able to use it.
Anyone can help me with that?
Thanks!
-
Hey!
I haven’t been able to replicate your issue.
Could you tell me what version of PHP you’re using and show me your build hook?Thanks!
0 -
Sure, here’s a portion of my YAML:
# The name of this app. Must be unique within a project. name: app # The type of the application to build. type: 'php:7.4' build: flavor: composer variables: php: "date.timezone": "Europe/Paris" "opcache.preload": "src/.preload.php" "opcache.memory_consumption": 256 "opcache.max_accelerated_files": 20000 "opcache.validate_timestamps": 0 realpath_cache_size: 4096K realpath_cache_ttl: 600 # env: # Tell Symfony to always install in production-mode. # APP_ENV: 'prod' # APP_DEBUG: 0 # The hooks that will be performed when the package is deployed. hooks: build: | set -e bin/console assets:install --no-debug bin/console cache:clear curl -sS https://platform.sh/cli/installer | php unset NPM_CONFIG_PREFIX curl -o- https://raw.githubusercontent.com/creationix/nvm/v0.35.2/install.sh | dash export NVM_DIR="$PLATFORM_APP_DIR/.nvm" [ -s "$NVM_DIR/nvm.sh" ] && \. "$NVM_DIR/nvm.sh" nvm current nvm install 12.16.1 npm install npm run quiet-build deploy: | set -e bin/console assets:install --symlink --relative public bin/console cache:clear bin/console doctrine:migrations:migrate --allow-no-migration --no-interaction unset NPM_CONFIG_PREFIX export NVM_DIR="$PLATFORM_APP_DIR/.nvm" [ -s "$NVM_DIR/nvm.sh" ] && \. "$NVM_DIR/nvm.sh" nvm use 12.16.1
0 -
I still haven’t been able to replicate your
npx
error using a similar build hook.If we follow what happens during your build hook once you’ve installed
nvm
, we have:-
nvm current
: should display “system” at this point. The node system version is 6.17.1 which comes withnpm
3.10.10.npx
is not available with thisnpm
version, as it only appeared with version 5. You cannot usenpx
using the node version that comes by default. -
nvm install 12.16.1
: you will get the specified node version, which comes withnpm
6.13.4 sonpx
will now be available. Trying to installnpx
after this step will get you into aEEXIST
error asnpx
can already be found in thebin
folder of your current node version. -
npm run quiet-build
: thequiet-build
npm script should be able to make use ofnpx
as well as everything that lives undernode_modules/.bin
. When running annpm
script, the localnode_modules/.bin
directory and thenpm
global’sbin
directory (in your case/app/.nvm/versions/node/v12.16.1/bin
) are automatically added to yourPATH
bynpm
.
If this clarification doesn’t help, let me know at which step you are trying to use
npx
and how you invoke the command (e.g. in an npm script or directly in your build hook) so I can try to mimic your situation as good as possible.0 -
-
Hey Rudy,
I agree with the steps and how you describe them:-
nvm current
displayssystem
-
nvm install 12.16.1
does its job -
npm run quiet-build
, too
But what I’m looking for is the ability to run
npx
afterwards, when the app is built and deployed.When connecting with
platform ssh
and runningnpx -v
I get-bash: npx: command not found
(which makes sense becausenode -v
displaysv6.17.1
). Is that normal?How come Node “switched back” to its system version?
How can I use thenode
/npm
/npx
tools installed bynvm
?But! I now understand why
npx
can’t run anything, that’s because the filesystem is read-only so it can’t download packages, right? But I could theorically call it with--no-install
if the packages are listed inpackages.json
and installed, right?0 -
-
Current fix (but looks like a hack to me):
Replace
npx --no-install
calls with/app/.nvm/versions/node/v12.16.1/bin/node /app/.nvm/versions/node/v12.16.1/bin/npx --no-install
0 -
Oh, if you want to be able to run
npx
via SSH directly in your container, then it’s a different story!When connecting with platform ssh and running npx -v I get -bash: npx: command not found (which makes sense because node -v displays v6.17.1). Is that normal?
How come Node “switched back” to its system version?This is normal. The different build hooks and your shell when you SSH into your container are different sessions. Therefore, environment variables set in your hooks won’t affect your environment when using SSH. Everything the
nvm.sh
script does has no effect anywhere else than in the hook it is being executed. After that, your environment is unaware ofnvm
's presence. Since node 12 has been installed vianvm
, the only available version to your system at this point is the default one: 6.17.1.How can I use the node/npm/npx tools installed by nvm?
Everything is there, but you need to set the environment variables. To do so, just add these lines in your
.environment
file:# This is necessary for nvm to work. unset NPM_CONFIG_PREFIX # Disable npm update notifier; being a read only system it will probably annoy you. export NO_UPDATE_NOTIFIER=1 # This loads nvm for general usage. export NVM_DIR="$PLATFORM_APP_DIR/.nvm" [ -s "$NVM_DIR/nvm.sh" ] && \. "$NVM_DIR/nvm.sh"
When connecting with
plaftorm ssh
, you should now be able to be in a situation where:$ command -v nvm nvm $ node -v 12.16.1 $ which npx /app/.nvm/versions/node/v12.16.1/bin/npx
Note: you will see a message saying
npm update check failed
when getting in your shell. This is due to an access right limitation when nvm wants to check for updates. You can ignore this. Just know that you will be runningnpm
andnpx
6.13.4 at this point (as opposed to 6.17.1 (as of today) in your hooks.)I now understand why npx can’t run anything, that’s because the filesystem is read-only so it can’t download packages, right? But I could theorically call it with --no-install if the packages are listed in packages.json and installed, right?
Yes, the filesystem is read-only so this will limit what you can do with
npx
but you don’t have to pass the--no-install
option.npx
will check for the command you want to execute in the local and globalbin
directories before trying to download anything so any already installed packages can be run by doingnpx [package]
directly. Also, even with the--no-install
option, trying to run a non-installed package will result in aEROFS
error asnpx
is going to try to perform write operations anyway.0
Please sign in to leave a comment.
Comments
6 comments