Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

ddev nvm use ... has no effect on subsequent ddev npm --version. #6013

Closed
1 task done
donquixote opened this issue Mar 24, 2024 · 21 comments
Closed
1 task done

ddev nvm use ... has no effect on subsequent ddev npm --version. #6013

donquixote opened this issue Mar 24, 2024 · 21 comments

Comments

@donquixote
Copy link

donquixote commented Mar 24, 2024

Is there an existing issue for this?

  • I have searched the existing issues

Output of ddev debug test

Expand `ddev debug test` diagnostic information
[...]

Expected Behavior

Steps:

  • ddev nvm use 20
  • ddev npm --version
  • ddev exec which npm

After "ddev nvm use 20": "Now using node v20.11.1 (npm v10.2.4)".
After "ddev npm --version": "10.2.4"
After "ddev exec which npm": "/home/lemonhead/.nvm/versions/node/v20.11.1/bin/npm"

Actual Behavior

After "ddev npm version": "6.14.18"
After "ddev exec which npm": "/home/lemonhead/.nvm/versions/node/v7.10.1/bin/npm"

On the other hand:
When I use ddev ssh and then run nvm use 20 and npm --version, I do get the updated npm version.

Steps To Reproduce

(I think this section belongs above the "Expected behavior", does it not?)

Anything else?

I tried a number of ways to set the npm version using nvm:

  • ddev nvm use 20
    • This seems to only have a temporary effect, and the change is lost on the next call to ddev npm.
  • ddev exec nvm use 20 and ddev exec npm --version.
    • Same effect as without exec.
  • Adding nvm install 20 && nvm use 20 in hooks/post-start//exec in .ddev/config.yaml.
    • This produces promising cli output on ddev restart, but then ddev npm --version still gives me the old version.
  • Setting nodejs_version: "20" in .ddev/config.yaml
    • No effect.
  • Adding RUN nvm install 20 and RUN nvm use 20 in .ddev/web-build/Dockerfile.
    • This gives me nvm not found, which indicates that nvm is not available at that time?

What actually did work was ddev nvm alias default 20.11.1.
Adding this in .ddev/config.yml in hooks/post-start//exec works, but:

  • I would like to avoid hard-coding a specific minor version.
  • Ideally I would like to rely on a .nvmrc that is placed in a subdirectory somewhere.

I did find related issues here in github, but they did not answer my question:

Btw, I am originally coming from this issue for Drupal Radix: https://www.drupal.org/project/radix/issues/3423681

@donquixote
Copy link
Author

Interesting conversation in discord:
https://discord.com/channels/664580571770388500/1199750600653549598/1199772207526723607

It seems this problem occurs if there are multiple node versions installed with nvm.

@donquixote
Copy link
Author

Actually, nodejs_version in .ddev/config.yml works after running ddev nvm alias default system.
And it seems persistent on container restart.

Still this leaves the question how nvm can be used effectively in ddev.

@rfay
Copy link
Member

rfay commented Mar 24, 2024

Yeah, there's really no real use for nvm any more in DDEV now that nodejs_version can use anything.

Do you need to review

Or is something really broken?

nvm is a pretty fragile shell based system, to be avoided where possible.

@donquixote
Copy link
Author

Do you need to review

Not sure what I would review there.

nvm is a pretty fragile shell based system, to be avoided where possible.

In the current project I work on, it is fine to use one global node and npm version.

I could imagine a Drupal project with multiple sub-themes that use different versions of npm.
In that case, it could be useful either to be able to switch version with nvm commands, or to have a mechanism that implicitly calls nvm use.. any time you run npm, and choose the correct version for the current directory.

The command for the first option would be ddev nvm alias default ..., because ddev nvm use is quite useless.

I think documentation still contains references to nvm which are not really helpful.

@rfay
Copy link
Member

rfay commented Mar 24, 2024

It seems to be working fine to me, what am I doing differently from you?

rfay@rfay-tag1-m1:~/workspace/d10$ ddev nvm install 19
Downloading and installing node v19.9.0...
Downloading https://nodejs.org/dist/v19.9.0/node-v19.9.0-linux-arm64.tar.gz...
######################################################################### 100.0%
Computing checksum with sha256sum
Checksums matched!
Now using node v19.9.0 (npm v9.6.3)
Creating default alias: default -> 19 (-> v19.9.0)
rfay@rfay-tag1-m1:~/workspace/d10$ ddev nvm use 19
Now using node v19.9.0 (npm v9.6.3)
rfay@rfay-tag1-m1:~/workspace/d10$ ddev exec node --version
v19.9.0

@donquixote
Copy link
Author

I think this is the difference:

Creating default alias: default -> 19 (-> v19.9.0)

Does this still happen if you install additional versions?

@rfay
Copy link
Member

rfay commented Mar 24, 2024

if I install node 6 for example, I do seem to have to
ddev nvm alias default 6

I also note that in your setup you're using nvm in a hook, which is possibly outside the bash environment that nvm depends on. nvm is not a binary at all, but instead a set of pretty silly bash includes, which is usually the main problem with using it.

(BTW, you have about 100 dead containers. You can clean up with docker rm -f $(docker ps -aq), does no harm on anything DDEV-related)

@donquixote
Copy link
Author

donquixote commented Mar 24, 2024

if I install node 6 for example, I do seem to have to
ddev nvm alias default 6

This is also my experience: A simple ddev nvm use 6 won't work.
I thought you need to specify 6.17.1, but apparently 6 is enough - this is good :)

I also note that in your setup you're using nvm in a hook,

I tried with this hook on and off, what you see is just a snapshot.
It did seems to work as exec-host: ddev nvm alias default ....

BTW, you have about 100 dead containers.

Thanks!
It happens..
but more concerning is the level of detail in this test output, from a privacy perspective.
I just removed the list of containers from the post, and will soon remove most of the output.

@rfay
Copy link
Member

rfay commented Mar 24, 2024

Yeah, it's your job to decide what you post publicly. When people have sensitive naming they usually edit beforehand. In DDEV v1.23.0 we'll have an improved version of ddev debug test that outputs to a file where it's easier for you to review before posting,

I don't think we can fix all the privacy issues from our end, but we're trying to make it easier for you.

@donquixote
Copy link
Author

I don't think we can fix all the privacy issues from our end, but we're trying to make it easier for you.

yeah, no problem, I just wanted to announce that I am removing some of it.

@rfay
Copy link
Member

rfay commented Mar 24, 2024

Oh, I just noticed that your original complaint is about npm. I thought it was about node

I seem to be setting npm set predictably.

Now with nvm set to 6:

$ ddev npm --version
3.10.10
$ ddev exec 'ls -l $(which npm)'
lrwxrwxrwx 1 rfay dialout 38 Apr  3  2019 /home/rfay/.nvm/versions/node/v6.17.1/bin/npm -> ../lib/node_modules/npm/bin/npm-cli.js

If I set default to 19:

rfay@rfay-tag1-m1:~/workspace/d10$ ddev nvm alias default 19
default -> 19 (-> v19.9.0)
rfay@rfay-tag1-m1:~/workspace/d10$ ddev exec 'ls -l $(which npm)'
lrwxrwxrwx 1 rfay dialout 38 Apr 10  2023 /home/rfay/.nvm/versions/node/v19.9.0/bin/npm -> ../lib/node_modules/npm/bin/npm-cli.js

I'm not at all sure you're looking at a problem in DDEV behavior compared to a problem in nvm behavior.

@donquixote
Copy link
Author

Oh, I just noticed that your original complaint is about npm. I thought it was about node

I need to have both node and npm on the right version.
And with nvm use or nvm alias, when the node version changes, the npm version also changes. With node 20.x I get npm 10.x, and both of these are fine.
(The ../lib/node_modules/npm/bin/npm-cli.js from your post is a relative path, still within the directory of a specific node version, so you do get different npm per node.)

The background here is in Drupal radix theme, the documentation says to run nvm use in a directory that contains an .nvmrc file. The .nvmrc is created by the subtheme generator, and all it says is lts/iron, which I assume means to pick the latest version with long-term support.

The problem was that the state change from ddev nvm use only lasts for that one command, so subsequent ddev npm would use the wrong version. This could be avoided by starting ddev ssh, and then running nvm use and npm from inside that shell - but this is not a desirable solution.

See https://www.drupal.org/project/radix/issues/3423681#comment-15513600

@rfay
Copy link
Member

rfay commented Mar 24, 2024

Please check carefully to see if your problem is with DDEV's use of nvm or if it's a problem with nvm itself. I suspect the latter.

You can use nvm inside the container - ddev ssh and just use it, with all its permutations. It's just nvm. If it behaves wrong there... then nvm is not doing what you want it to do, but I don't think it has anything to do with DDEV.

@rfay
Copy link
Member

rfay commented Mar 24, 2024

The background here is in Drupal radix theme, the documentation says to run nvm use in a directory that contains an .nvmrc file. The .nvmrc is created by the subtheme generator, and all it says is lts/iron, which I assume means to pick the latest version with long-term support.

Ah, thanks for that. DDEV won't know how to do that, and certainly ddev nvm won't; it always runs in the root of the project. However, you may be able to do what you want using nvm inside the container.

@donquixote
Copy link
Author

To be clear:
At this point I don't think there is a "bug" in ddev.

However, the documentation could be updated where it mentions nvm:

  • Run ddev node --version and ddev npm --version to check which version is currently active.
  • Option 1 (recommended): Use system node + npm in the container:
    • Set node version is using nodejs_version in .ddev/config.yaml.
    • Run ddev nvm alias default system if needed, to stop nvm overrides.
  • Option 2 (if you need to switch between multiple versions): Use nvm to manage node + npm:
    • To change node version with nvm from the host system to e.g. node version 20.x, run ddev nvm alias default 20.
    • To temporarily change node version with nvm from inside the container (from a ddev ssh session), run nvm use 20. Here the nvm alias default 20 will have no effect, until you start a new ssh session.
    • Add ddev nvm install 20 && ddev nvm alias default 20 as hook in .ddev/config.yaml.

For the last point about the hook I am not sure. I think these only need to run when the container is created, not whenever it is started.
Perhaps the better solution is to always start with system node + npm, and only use nvm to temporarily switch.

This will help people like this, https://discord.com/channels/664580571770388500/1199750600653549598

@rfay
Copy link
Member

rfay commented Mar 24, 2024

Could you take a run at a docs PR? Click the pencil in the upper right of the page.

There is certainly confusion about this, and I'm really glad we can now specify a specific nodejs_version (and any nodejs_version) thanks to @hanoii

People do still complain occasionaly about being able to separately control the npm version.

The docs were recently updated to try to suggest that people not use nvm unless they really need it for something.

@donquixote
Copy link
Author

I can try, when I have time.
I first need to get myself an overview which pages need editing, and perhaps get a bit more practice with the commands.

@stasadev
Copy link
Member

stasadev commented Apr 8, 2024

It would be good to have this information in a future stable release, so:

@rfay rfay closed this as completed in 30ba6c8 Apr 9, 2024
@donquixote
Copy link
Author

Thanks for stepping up @stasadev !
I kind of dropped the ball with this one :)

@jeroenimpres
Copy link
Contributor

hey all, thanks for clarifying this all, this is a very useful thread! I experienced the same thing when I came into a project that was already setup and running for a year or so. There were some nvm statements in the post-start and when we were upgrading this codebase (and node/npm version) we got into the same trouble. The config.yaml stated 18, npm on the container would 'reset' to 15, even when we had a .nvmrc file in place.
I knew that a single issues command of ddev nvm use would not work for the subsequent commands, but did not know what the best approach to fixing it was.

The wording of "Use of ddev nvm is discouraged because nodejs_version..." is perfect, since we have a choice, but when there are no special needs of multiple node versions on one container, the nodejs_version is now the best option in my opinion.

Thanks again, I was search for my problem in the past issues, and I already found it. Thanks so much!

@stasadev
Copy link
Member

I thought nvm use changes the version of the node after ddev ssh and saves it, but that turned out to be wrong, it resets it back after the session ends:

$ ddev ssh
$ nvm install 18
$ nvm install 16
$ nvm use 16
$ nvm current
v16.20.2
$ exit
$ ddev ssh
$ nvm current
v18.20.2

Finally found this answer:

nvm use isn't meant to persist - it's only for the lifetime of the shell.

I don't know why there are so many tutorials that show and recommend nvm use at all.
IMO it should be called nvm temp-use.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

4 participants