【问题标题】:npm install from within a docker fails when ran in synology dsm but works locally在 Synology dsm 中运行时,从 docker 中安装 npm 失败,但在本地工作
【发布时间】:2021-01-11 23:21:11
【问题描述】:

好吧,在尝试自动化构建多一点的过程中,构建被移动到了一个 docker - 然而,虽然这在我们的本地设置中有效,但在远程服务器中却不起作用。

构建过程的 dockerfile 如下所示;

FROM node:14-alpine
RUN apk update
RUN apk upgrade
RUN apk add rsync
RUN apk add git less openssh

RUN mkdir /javascript
WORKDIR /javascript

RUN npm install flow-remove-types -g

ENTRYPOINT npm ci

在构建之后通过以下方式调用它:

sudo docker run -it --volume=/home/paul/project/javascript:/javascript \
    --volume=/home/paul/.ssh:/home/node/.ssh \
    --volume=/home/paul/.ssh:/root/.ssh \
    --volume=/home/paul/.npm:/home/node/.npm \
    --entrypoint "sh" buildimagedocker

(出于测试目的更改了入口点)。

如果我然后启动并输入“npm install”或“npm ci”,我会收到以下错误:

npm ERR! Error while executing:
npm ERR! /usr/bin/git ls-remote -h -t ssh://git@<GITSERVER>
npm ERR! 
npm ERR! No user exists for uid 1028
npm ERR! fatal: Could not read from remote repository.
npm ERR! 
npm ERR! Please make sure you have the correct access rights
npm ERR! and the repository exists.
npm ERR! 
npm ERR! exited with error code: 128

npm ERR! A complete log of this run can be found in:
npm ERR!     /root/.npm/_logs/2020-09-25T15_18_53_397Z-debug.log

但是从 git 手动克隆工作正常 - 所以它一定是 npm 安装的问题。

此外,同一个 docker 在我的本地电脑上也可以正常工作,只是在 synology dsm 中会出现问题。

我看到了同样的问题报告here。然而,它已经被表示为“固定”。我测试了当前的 npm 版本:

npm --version: 6.14.8

那么出了什么问题,我该如何解决这个问题?

编辑,最大的不同是在我的本地电脑中,文件权限看起来像:

drwxr-xr-x    2 node     node          4096 Sep 25 13:45 bin
drwxr-xr-x   10 node     node          4096 Sep 25 13:45 build
drwxr-xr-x    2 node     node          4096 Sep 25 13:45 config

在远程时它看起来像:

drwxr-xr-x    2 1028     users         4096 Sep 25 15:18 bin
drwxr-xr-x    2 1028     users         4096 Sep 25 15:18 build
drwxr-xr-x    2 1028     users         4096 Sep 25 15:18 config

在 docker 之外,相同的文件看起来像(本地):

drwxr-xr-x  2 paul paul   4096 sep 25 15:45 bin
drwxr-xr-x 10 paul paul   4096 sep 25 15:45 build
drwxr-xr-x  2 paul paul   4096 sep 25 15:45 config

远程:

drwxrwxrwx+   2 PaulWeijtens users   4096 Sep 25 17:18 bin
drwxrwxrwx+   2 PaulWeijtens users   4096 Sep 25 17:18 build
drwxrwxrwx+   2 PaulWeijtens users   4096 Sep 25 17:18 config

【问题讨论】:

  • @您使用的是哪个操作系统?
  • @RichardRublev 在我的本地安装 ubuntu,而远程是 Synology dsm。但是docker的想法是不用担心主机操作系统?
  • 我同意,隔离才是重点。
  • 这是您安装的卷的权限错误。它们在本地设置为用户 ID 1028,但容器中不存在此用户 ID。
  • 还有一点需要注意的是,只有在存储库中有 git 包时才会发生这种情况。

标签: node.js docker npm


【解决方案1】:

这确实是一个权限问题,但并没有像 doublesharp 的答案所解释的那样解决。我通过重构文件的工作方式来修复它。在这个答案中,我将尝试解释我是如何以及为什么做这些事情的(对于未来的 denvercoder9s)。我可能不完全正确,请在 cmets 中纠正我,或更新答案(我刚刚开始“了解”这个)。

/home/node/.ssh/root/.ssh 下的文件不属于当前正在运行的用户。通常这不是问题,因为程序是从 docker 内部以“root”身份读取的。

虽然主进程确实在alpine:node docker 中以root 身份运行,但npm 运行的任何内容似乎都会降低node 用户的权限。出于这个原因,以用户 1028 运行 docker 不起作用,文件仍然像用户 node 一样被访问。

因此解决方案是更改文件权限,但由于在卷中这样做也会更改主机上的权限,因此我选择重构 docker 并将文件复制到 docker使用Dockerfile

COPY local/ssh/ /root/.ssh/
COPY local/ssh/ /home/node/.ssh/

然而,这意味着该文件具有777 作为权限掩码,并且 ssh 抱怨(相当激烈)它不会接受其他人可读的文件。运行chmod 将掩码挂起到 400 但是又出现了权限问题,因为npm 不是以root 或创建 docker 的同一用户运行,因此在运行期间无法访问文件。所以必须将目录所有权更改为用户node

最后,由于远程的主目录与本地电脑的位置不同,我选择不使用 home 作为 ssh 位置。而是使用本地 ssh 目录。

生成的 dockerfile 现在看起来像:

FROM node:14-alpine
RUN apk update
RUN apk upgrade

RUN mkdir /javascript
WORKDIR /javascript


RUN npm install flow-remove-types -g

COPY --chown=node:node local/ssh/ /root/.ssh/
COPY --chown=node:node local/ssh/ /home/node/.ssh/
RUN chmod 400 /root/.ssh/id_rsa
RUN chmod 400 /home/node/.ssh/id_rsa

ENTRYPOINT chown -R node:node . && npm ci

和电话一样

sudo docker run -it --volume=/home/paul/project/javascript:/javascript \
    --volume=/home/paul/.npm:/home/node/.npm \
    --entrypoint "sh" buildimagedocker

需要注意的重要一点是alpine:node docker 将运行npm 进程而不是使用node,而不是root。更改 docker 的用户 ID 对此没有影响。

【讨论】:

    【解决方案2】:

    您正在尝试安装到已在主机上将权限设置为用户 ID 1028 但在容器中不存在的已安装卷,因此您无法写入该卷。要解决此问题,您可以将卷上的权限设置为更加开放,在容器内创建具有相同 ID 的用户,或者使用 -u 参数启动容器以指定 UID。

    有关指定 UID 的信息,请参阅最后一行,有关 GID/UID with dockerDocker documentation for USER 的这一部分的更多信息。

    sudo d

    ocker run -it --volume=/home/paul/project/javascript:/javascript \
        --volume=/home/paul/.ssh:/home/node/.ssh \
        --volume=/home/paul/.ssh:/root/.ssh \
        --volume=/home/paul/.npm:/home/node/.npm \
        --entrypoint "sh" buildimagedocker \
        -u 1028:1028 
    

    一般也不建议将node_modules及相关文件与容器共享,因为如果主机和容器是不同的操作系统、节点版本等,它们将不起作用。

    【讨论】:

    • 嗯,但是我如何以这种方式共享“当前用户”?无需硬输入ID? -- 还有为什么它会在我的本地电脑上工作,其中所有者是“paul”,并且在节点容器中你可以看到用户“paul”不存在并且所有权更改为“node”
    • 依赖当前用户会有问题,最好设计一个不同的设置,但是如果你想使用当前的 UID,你可以这样做:-u $(id -u):$(id -g)
    • 这些文件是由另一个 docker 提供的(纯粹是 git 来下载它),这个 docker 将构建文件,然后将其传递给一个测试 docker。 - 我仍然无法理解为什么它可以在本地工作但不能在远程工作。为什么本地 docker 会“映射”用户权限,而远程不会?
    • 这也解决问题,在我将其提供给正确的用户 ID (1028) 和组 ID (100) 后会弹出完全相同的错误。跨度>
    猜你喜欢
    • 1970-01-01
    • 2023-01-10
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-10-27
    • 2013-08-10
    • 2022-01-26
    相关资源
    最近更新 更多