在 Dockerfile 中安装 nodejs 和 npm

Ste*_*fan 2 node.js npm docker

上下文

我有一个 Dockerfile 来创建一个包含 apache 网络服务器的图像。但是,我也想使用 Dockerfile 构建我的网站,以便构建过程不依赖于开发人员的本地环境。请注意,docker 容器仅用于本地开发而不用于生产。

问题

我有这个 Dockerfile:

FROM httpd
RUN apt-get update -yq
RUN apt-get -yq install curl gnupg
RUN curl -sL https://deb.nodesource.com/setup_12.x | bash
RUN apt-get update -yq
RUN apt-get install -yq \
        dh-autoreconf=19 \
        ruby=1:2.5.* \
        ruby-dev=1:2.5.* \
        nodejs
Run Code Online (Sandbox Code Playgroud)

我构建它:

sudo docker build --no-cache .
Run Code Online (Sandbox Code Playgroud)

构建成功完成,这是输出的一部分:

Step 9/15 : RUN curl -sL https://deb.nodesource.com/setup_12.x | bash
 ---> Running in e6c747221ac0
......
......
......
Removing intermediate container 5a07dd0b1e01
 ---> 6279003c1e80
Successfully built 6279003c1e80
Run Code Online (Sandbox Code Playgroud)

但是,当我使用这个在容器中运行图像时:

sudo docker container run --rm -it --name=debug 6279003c1e80 /bin/bash
Run Code Online (Sandbox Code Playgroud)

然后在apt-cache policy容器内部执行时,它不会显示应该使用 curl 命令添加的存储库。同样在执行apt-cache policy nodejs时显示已安装旧版本。

但是,当我然后在容器内运行以下内容时:

curl -sL https://deb.nodesource.com/setup_12.x | bash
apt-cache policy
apt-cache policy nodejs
Run Code Online (Sandbox Code Playgroud)

它显示我添加了存储库,并显示了较新的 nodejs 版本可用。

那么为什么RUN在 docker 文件中使用 curl 命令时它似乎不起作用,但是当从 shell 在容器中手动执行它时,它却起作用了?我怎样才能解决这个问题?

更新

  • 请注意,为了防止缓存问题,我使用了 --no-cache 标志。
  • 我还删除了所有容器并sudo docker system prune重建了映像,但没有成功。
  • 我尝试按照用户“hmm”的建议将所有内容捆绑在一个 RUN 命令中(因为这是 apt 命令的最佳实践):
RUN apt-get update -yq \
    && apt-get -yq install curl gnupg && \
    && curl -sL https://deb.nodesource.com/setup_12.x | bash \
    && apt-get update -yq \
    && apt-get install -yq \
        dh-autoreconf=19 \
        ruby=1:2.5.* \
        ruby-dev=1:2.5.* \
        nodejs \
    && rm -rf /var/lib/apt/lists/*
Run Code Online (Sandbox Code Playgroud)

cha*_*ash 10

您可能会遇到缓存图层的问题。Dockerfile 最佳实践文档中有很长的部分是关于使用 apt-get 的。大概值得一读。

要点是 Docker 不识别 first 和 second 之间的任何区别RUN apt-get update,也不知道这apt-get install取决于新apt-get update层。

解决方案是将所有这些组合成一个RUN命令(推荐)或在构建过程中禁用缓存 ( docker build --no-cache)。

RUN apt-get update -yq \
    && apt-get -yq install curl gnupg ca-certificates \
    && curl -L https://deb.nodesource.com/setup_12.x | bash \
    && apt-get update -yq \
    && apt-get install -yq \
        dh-autoreconf=19 \
        ruby=1:2.5.* \
        ruby-dev=1:2.5.* \
        nodejs
Run Code Online (Sandbox Code Playgroud)

编辑:在本地运行您的 Dockerfile,我注意到curl命令没有输出。删除-s标志后(静默失败),您可以看到由于无法验证服务器的 SSL 证书而失败:

curl: (60) SSL certificate problem: unable to get local issuer certificate
More details here: https://curl.haxx.se/docs/sslcerts.html

curl failed to verify the legitimacy of the server and therefore could not
establish a secure connection to it. To learn more about this situation and
how to fix it, please visit the web page mentioned above.
Run Code Online (Sandbox Code Playgroud)

该解决方案问题是安装ca-certificates运行前curl。我已经更新了RUN上面的命令。