npm 错误!为 Node 项目创建 Docker 镜像时,跟踪器“idealTree”已经存在

Jay*_*dha 37 docker dockerfile

我创建了一个名为 simpleWeb 的 node.js 项目。该项目包含 package.json 和 index.js。

索引.js

    const express = require('express');
    
    const app = express();
    
    app.get('/', (req, res) => {
      res.send('How are you doing');
    });
    
    app.listen(8080, () => {
      console.log('Listening on port 8080');
    });
Run Code Online (Sandbox Code Playgroud)

包.json


    {
        "dependencies": {
          "express": "*"
        },
        "scripts": {
          "start": "node index.js"
        }
      }
Run Code Online (Sandbox Code Playgroud)

我还创建了一个 Dockerfile 来为我的 node.js 项目创建 docker 镜像。

文件

# Specify a base image
FROM node:alpine

# Install some dependencies 
COPY ./ ./
RUN npm install

# Default command
CMD ["npm", "start"]
Run Code Online (Sandbox Code Playgroud)

虽然我尝试使用“docker build”构建 docker 镜像。命令它抛出以下错误。

错误日志

simpleweb » docker build .                                                    ~/Desktop/jaypal/Docker and Kubernatise/simpleweb
[+] Building 16.9s (8/8) FINISHED
 => [internal] load build definition from Dockerfile                                                                         0.0s
 => => transferring dockerfile: 37B                                                                                          0.0s
 => [internal] load .dockerignore                                                                                            0.0s
 => => transferring context: 2B                                                                                              0.0s
 => [internal] load metadata for docker.io/library/node:alpine                                                               8.7s
 => [auth] library/node:pull token for registry-1.docker.io                                                                  0.0s
 => [internal] load build context                                                                                            0.0s
 => => transferring context: 418B                                                                                            0.0s
 => [1/3] FROM docker.io/library/node:alpine@sha256:5b91260f78485bfd4a1614f1afa9afd59920e4c35047ed1c2b8cde4f239dd79b         0.0s
 => CACHED [2/3] COPY ./ ./                                                                                                  0.0s
 => ERROR [3/3] RUN npm install                                                                                              8.0s
------
 > [3/3] RUN npm install:
#8 7.958 npm ERR! Tracker "idealTree" already exists
#8 7.969
#8 7.970 npm ERR! A complete log of this run can be found in:
#8 7.970 npm ERR!     **/root/.npm/_logs/2020-12-24T16_48_44_443Z-debug.log**
------
executor failed running [/bin/sh -c npm install]: exit code: 1
Run Code Online (Sandbox Code Playgroud)

它上面的日志文件提供了一个路径“/root/.npm/_logs/2020-12-24T16_48_44_443Z-debug.log”,我可以在其中找到完整的日志。

但是,我的本地机器上不存在上述文件。

我不明白这是什么问题。

Pri*_*ora 92

这个问题是由于 nodejs 从 15 版本开始的变化而发生的。当没有指定 WORKDIR 时,在容器的根目录中执行 npm install,这导致了这个错误。在 WORKDIR 指定的容器的项目目录中执行 npm install 可以解决该问题。

使用以下 Dockerfile:

# Specify a base image
FROM node:alpine

#Install some dependencies

WORKDIR /usr/app
COPY ./ /usr/app
RUN npm install

# Set up a default command
CMD [ "npm","start" ]
Run Code Online (Sandbox Code Playgroud)

  • 发生此问题的原因是 Nodejs 从版本 15 开始进行了更改。当未指定 WORKDIR 时,会在容器的根目录中执行 npm install,从而导致此错误。从容器中的项目目录中执行 npm install 可以解决该问题。 (3认同)
  • 我还是有点困惑,容器的根不是“/”吗?COPY ./ ./ 应该可以工作,因为我们正在将项目文件复制到根目录“/” (3认同)
  • 那么以前存放它的地方是什么?有关系吗? (2认同)

Eva*_*oll 42

全局安装

如果您想在工作目录之外全局安装一个带有 的包package.json,您应该使用该-g标志。

npm install -g <pkg>
Run Code Online (Sandbox Code Playgroud)

如果您使用的 CI 软件semantic-release是内置在节点中并且您尝试将其安装在工作目录之外,则可能会触发此错误。


did*_*dof 12

正确答案基本正确,但是我试了还是不行。原因如下:

WORKDIR指定COPY它后面的 的上下文。已经指定了上下文,./usr/app要求从./(您正在工作的目录)复制到其中的上下文是错误的,./usr/app因为这会在容器中产生以下结构:./usr/app/usr/app.

结果CMD ["npm", "start"],后面跟着WORKDIR( ./usr/app)指定的地方没有找到package.json.

我建议使用这个 Dockerfile:

FROM node:alpine

WORKDIR /usr/app

COPY ./ ./

RUN npm install

CMD ["npm", "start"]
Run Code Online (Sandbox Code Playgroud)

  • 为什么在复制所有源文件后运行 npm i,这不会缓存?我建议您阅读 Docker 层以及为什么应该按照从最不经常更改到最常更改的顺序对层进行排序 (4认同)
  • 他使用了 /usr/app 而不是 ./usr/app。在后一种情况下,您最终会创建重复的子目录 (3认同)

You*_*sef 6

您应该在 COPY 指令之前指定 WORKDIR,以确保在所有应用程序文件所在的目录中执行 npm install。以下是完成此操作的方法:

WORKDIR /usr/app

# Install some dependencies
COPY ./ ./
RUN npm install
Run Code Online (Sandbox Code Playgroud)

请注意,您可以简单地“COPY ./(当前本地目录)./(由于 WORKDIR 指令,容器目录现在是 /usr/app)”而不是“COPY ./ /usr/app”

现在使用 WORKDIR 指令的充分理由是避免将应用程序文件和目录与容器的根文件系统混合(以避免覆盖文件系统目录,以防应用程序目录上有类似的目录标签)

还有一件事。对配置进行分段是一个很好的做法,这样当您在 index.js 中进行更改时(因此您需要重建图像),您将不需要在打包时运行“npm install”。 json没有被修改。

您的应用程序非常基本,但想想一个大型应用程序,其中“npm install”应该需要几分钟。

为了利用 Docker 的缓存过程,您可以将配置分段如下:

WORKDIR /usr/app

# Install some dependencies
COPY ./package.json ./
RUN npm install
COPY ./ ./ 
Run Code Online (Sandbox Code Playgroud)

这指示 Docker 在未触及 package.json 时缓存第一个 COPY 和 RUN 命令。因此,当您更改 index.js 并重建映像时,Docker 将使用先前指令(第一个 COPY 和 RUN)的缓存并开始执行第二个 COPY。这使您的重建速度更快。

图像重建示例:

 => CACHED [2/5] WORKDIR /usr/app                                                                                                       0.0s
 => CACHED [3/5] COPY ./package.json ./                                                                                                 0.0s
 => CACHED [4/5] RUN npm install                                                                                                        0.0s
 => [5/5] COPY ./ ./
Run Code Online (Sandbox Code Playgroud)


Mic*_*ens 5

虽然有点晚了,但对于不想为安装程序创建 Dockerfile 的项目,也可以从临时容器运行安装程序。这提供了对 Node CLI 的完全访问权限,而无需将其安装在主机上。

该命令假设它是从项目的根目录运行的,并且存在一个 package.json 文件。该-v $(pwd):/app选项将当前工作目录挂载到容器中的 /app 文件夹,将安装的文件同步回主机目录。该-w /app选项将图像的工作目录设置为 /app 文件夹。该--loglevel=verbose选项会导致安装命令的输出变得冗长。更多选项可以在官方 Node Docker Hub页面上找到。

docker run --rm -v $(pwd):/app -w /app node npm install --loglevel=verbose
Run Code Online (Sandbox Code Playgroud)

就我个人而言,我使用 Makefile 来存储几个临时容器命令,这些命令与构建过程分开运行速度更快。但当然,一切皆有可能:)