如何通过单行docker run命令使用node镜像生成当前目录package.json
问题原因
你执行报错的核心原因是node:18-alpine3.14官方镜像默认的ENTRYPOINT是node可执行程序,你在命令末尾传入的字符串会被直接当作参数传给node进程,node会把这串内容识别为要运行的JS文件路径,自然会抛出找不到模块的错误。
除此之外你的原命令还有3个容易导致执行不符合预期的问题:
- 挂载路径使用了
~/tmp,容器内的~默认指向root用户家目录/root,路径解析结果很可能和你的预期不符 - 加了
-d后台运行参数,npm init是交互式命令,后台运行时你无法输入配置项,也看不到执行输出 - 当前路径变量写法错误:Linux/macOS环境下需要用大写
$PWD或$(pwd)获取当前工作目录,Windows PowerShell下需要用${PWD},小写$pwd在多数Shell环境下是空值
正确命令
1. 最简写法(推荐)
直接通过Docker的-w参数指定容器工作目录,不需要额外执行cd命令,也不需要手动覆盖入口点:
非交互生成默认package.json(不需要手动填配置)
# Linux/macOS docker run --rm -v $(pwd):/app -w /app node:18-alpine3.14 npm init -y
# Windows PowerShell docker run --rm -v ${PWD}:/app -w /app node:18-alpine3.14 npm init -y
交互式生成(手动填写包名、版本等配置)
加-it参数开启交互式终端即可:
# Linux/macOS docker run --rm -it -v $(pwd):/app -w /app node:18-alpine3.14 npm init
参数说明:
--rm:容器执行完命令后自动删除,避免留存大量状态为exited的无用容器-v 本地路径:/app:将本地当前工作目录挂载到容器内的绝对路径/app,避开~路径解析的不确定性-w /app:直接设置容器启动后的工作目录为/app,等价于进入容器后自动执行cd /app-it:绑定标准输入、分配虚拟终端,支持交互式输入内容
2. 复合命令写法
如果你确实需要执行多步串联的Shell命令(比如必须先cd再执行其他操作),可以显式指定容器入口点为Shell,再把命令串传给Shell执行:
# Linux/macOS 示例 docker run --rm -it -v $(pwd):/app --entrypoint sh node:18-alpine3.14 -c "cd /app && npm init"
这种写法下,--entrypoint sh会把容器默认的node入口点替换成sh,后面的-c "命令串"就会交给sh解析执行,不会再被当成参数传给node。
内容的提问来源于stack exchange,提问作者marcell-janovszki
相关产品推荐
相关产品推荐

