Skip to content

huayuprophet/dnvm

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

2 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

English | 中文

Docker Node Version Mux (dnvm)

Run Node.js in Docker containers — no need to install Node.js or nvm on your host machine.

No need to install Node.js or nvm on your host. Freely use and switch Node versions with just Docker Desktop.

Overview

Docker Node Version Mux (Multiplexer) for Windows is a Windows batch script tool that runs Node.js through Docker containers.

No need to install Node.js, no need to learn version management tools. Just Docker Desktop, and you can use any Node.js version in any directory.

The core principle is simple: each command (node, npm, npx) is wrapped in a .cmd batch script that internally calls docker run to start the corresponding node:*-alpine image, mounting the current working directory to /app inside the container.

You can even use the following command directly instead of node, npm, npx:

docker run --rm -it --init --network host -v "$(pwd):/app" -v npm-config-data:/root -w /app node:22-alpine npm install axios

Features

  • No Node.js installation required — No Node.js runtime needed on the host
  • Free version switching — Append +version to any command to temporarily switch Node versions (e.g., +20, +18, +22)
  • Default version config — Set a default version during installation for daily use
  • Command prefix support — Configure a command prefix (e.g., d) to generate dnpm, dnode, dnpx, avoiding conflicts with system commands
  • Generic shell executionnodesh runs any shell command inside a container (ls, tar, curl, etc.)
  • Port mapping — Supports --network host or custom port mapping ranges for running web services
  • Persistent npm cache — Uses Docker volume npm-config-data to persist npm configuration across runs
  • Ready to use — Install script automatically configures PATH, ready to use from any terminal

System Requirements

  • OS: Windows 10/11 (or Windows Server 2016+)
  • Docker: Docker Desktop for Windows (must be installed and running)
  • PowerShell: For running install/uninstall scripts

Quick Start

1. Install

# Clone or download this project, then run in the project directory:
powershell -ExecutionPolicy Bypass -File .\install.ps1

The install script will guide you through the following configuration:

  1. Command prefix — Enter a prefix to avoid conflicts with system commands (e.g., enter d to generate dnpm, dnode, dnpx; leave empty for npm, node, npx)
  2. Default Node version — Default 22, can specify other versions like 20, 18
  3. Port mapping — Enter 0 for --network host, or a port/range like 12480-12499 for -p 12480-12499:12480-12499
  4. Add to PATH — Choose whether to add the bin\ directory to your user PATH

2. Usage

After installation, open a new terminal window and use the following commands:

(with prefix d as an example)

# Check Node version
dnode --version

# Install dependencies
dnpm install

# Run npx commands
dnpx create-vite@latest

# Use a specific Node version (temporary switch)
dnpm +20 install
dnode +18 --version
dnpx +22 create-react-app my-app

# Run arbitrary shell commands in a container
nodesh ls -la
nodesh tar -czvf demo.tar.gz demo/
nodesh +20 node -e "console.log('Hello from Node 20')"

3. View Help

nodesh help

4. Uninstall

powershell -ExecutionPolicy Bypass -File .\uninstall.ps1

The uninstall script will:

  • Delete the bin\ directory (all generated command files)
  • Delete the var\ directory (configuration files)
  • Remove bin\ from the user PATH

Note: Docker images and volumes are not automatically removed. To clean up manually:

docker volume rm npm-config-data
docker system prune -a

5. Test

powershell -ExecutionPolicy Bypass -File .\test.ps1

The test script verifies that all commands work correctly, including version switching and file operations.

Command Reference

Command Description
{prefix}node Run Node.js in Docker
{prefix}npm Run npm in Docker
{prefix}npx Run npx in Docker
nodesh Run any shell command in Docker

{prefix} is the command prefix configured during installation, empty by default.

Version Switching

All commands support temporary Node version switching via the +version parameter:

# Use Node 20
dnode +20 -e "console.log(process.version)"

# Install dependencies with Node 18
dnpm +18 install

# Run npx with Node 22
dnpx +22 create-vue@latest

The version must correspond to a node:* image tag on Docker Hub (e.g., 20, 18, 22, 23, etc.).

Port Mapping

The port mapping configured during installation determines how the container exposes ports:

  • 0 — Uses --network host mode (requires Host networking enabled in Docker Desktop settings)
  • Other values — Uses -p PORT:PORT mapping, e.g., 12480-12499 maps ports 12480 through 12499

Project Structure

nodejs-docker/
├── install.ps1          # Install script
├── uninstall.ps1        # Uninstall script
├── test.ps1             # Test script
├── README.md            # This file (English)
├── README-zh.md         # Chinese documentation
├── bin/                 # Generated command files (created during install)
│   ├── {prefix}node.cmd
│   ├── {prefix}npm.cmd
│   ├── {prefix}npx.cmd
│   └── nodesh.cmd
├── lib/                 # Command templates
│   ├── node.cmd-simple
│   ├── npm.cmd-simple
│   ├── npx.cmd-simple
│   └── nodesh.cmd-simple
└── var/                 # Configuration files (created during install)
    ├── CMD_PREFIX
    ├── DEFAULT_NODE_VERSION
    └── EXPOSE_PORT

How It Works

Each .cmd script is essentially a wrapper around docker run:

docker run --rm -it --init [network args] \
  -v "%CD%:/app" \              # Mount current directory to container
  -v npm-config-data:/root \    # Persist npm cache
  -w /app \                     # Set working directory to /app
  "node:{version}-alpine" \     # Use specified Node image
  {command} {args}              # Execute command
  • --rm — Automatically remove container on exit
  • -it — Interactive terminal
  • --init — Use init process for signal handling
  • npm-config-data volume — Persists npm configuration and global cache across runs

FAQ

Q: What if I already have Node.js installed on my system?

The install script detects existing Node.js installations. If a conflict is detected, we recommend:

  1. Uninstall the system Node.js, or
  2. Set a command prefix during installation (e.g., d), and use dnode, dnpm to avoid conflicts

Q: How do I change the default Node version?

Re-run install.ps1.

Or directly edit the var\DEFAULT_NODE_VERSION file.

Q: How do I change the command prefix?

Re-run install.ps1.

Or edit the var\CMD_PREFIX file, then manually rename the corresponding command files in the bin\ directory (e.g., rename npm.cmd to dnpm.cmd).

Q: How do I change the port mapping?

Re-run install.ps1.

Or directly edit the var\EXPOSE_PORT file.

Q: Why doesn't --network host work? How do I enable it?

--network host mode requires the corresponding feature to be enabled in Docker Desktop first. Enable it as follows:

  1. Open Docker Desktop
  2. Click the ⚙️ Settings icon in the top right
  3. Go to ResourcesNetwork
  4. Check Enable host networking (requires Docker Desktop 4.29+)
  5. Click Apply & Restart

If you can't find this option, make sure your Docker Desktop version is 4.29 or higher.

Q: Do I need to change the PowerShell execution policy?

No. node, npm, npx, and nodesh are all .cmd batch files — they are not affected by PowerShell's ExecutionPolicy and work in both PowerShell and cmd.

PowerShell execution policy only affects .ps1 scripts (like install.ps1, uninstall.ps1, test.ps1), which is why those need -ExecutionPolicy Bypass to run.

For daily use of dnode, dnpm, nodesh, etc., just type them in your terminal — no extra setup needed.

Q: Is npm configuration preserved?

Yes. npm configuration is stored in the Docker volume npm-config-data, so it persists even when containers are removed.

Q: Why not mount /usr/local/lib/node_modules to a named volume directly?

Some might want to mount /usr/local/lib/node_modules separately. This is not recommended for the following reasons:

  • Version conflicts — Global packages from different Node versions may be incompatible.
  • Permission issues — The ownership and permissions of /usr/local/lib/node_modules in Alpine images may not match the mounted volume, causing npm install -g to fail.
  • Cross-version pollution — Switching versions may cause global commands to point to incompatible native modules.
  • Against design philosophy — Simplicity, lightness, and local dependencies are the project's design philosophy. Installing components globally goes against the container mindset.

That said, you can design separate volume names for different Node versions to solve compatibility issues. If you really need custom mount behavior, edit the .cmd-simple template files in the lib\ directory, modify the volume mount section, then re-run install.ps1.

License

MIT

About

Docker Node Version Mux (dnvm). A Windows scripting tool for running multiple versions of Node.js via Docker containers.

Resources

License

Stars

Watchers

Forks

Releases

No releases published

Packages

 
 
 

Contributors