docker 构建 + 私有 NPM(+ 私有 docker 集线器)

docker build + private NPM (+ private docker hub)

我有一个 运行 在 Docker 容器中的应用程序。它需要来自公司私有 NPM 注册表 (Sinopia) 的一些私有模块,访问这些模块需要用户身份验证。 Docker 文件是 FROM iojs:latest.

我试过:

1) 在项目根目录创建一个.npmrc 文件,这实际上没有任何区别,npm 似乎忽略了它 2) 使用环境变量 NPM_CONFIG_REGISTRYNPM_CONFIG_USER 等,但用户没有登录。

基本上,我似乎无法在 docker build 进程中对用户进行身份验证。我希望有人可能已经 运行 解决了这个问题(似乎是一个足够明显的问题)并且会有解决它的好方法。

(最重要的是,我在 Docker Hub 上使用自动构建(在推送时触发),以便我们的服务器可以使用预构建图像访问私有 Docker 注册表。)

有没有好的方法: 1) 在构建时为 NPM 注入凭据(这样我就不必向我的 Docker 文件提交凭据)或者 2)用我没有想到的另一种方式做这件事 ?

我在为您的 node.js / io.js 容器 (you/iojs) 创建基本映像时找到了一个有点优雅的解决方案:

  1. 使用您要用于 docker
  2. 的用户登录您的私人 npm 注册表
  3. 复制这生成的.npmrc文件

示例.npmrc

registry=https://npm.mydomain.com/
username=dockerUser
email=docker@mydomain.com
strict-ssl=false
always-auth=true
//npm.mydomain.com/:_authToken="someAuthToken"
  1. 创建一个 Dockerfile 来适当地复制 .npmrc 文件。

这是我的 Dockerfile(基于 iojs:onbuild):

FROM iojs:2.2.1

MAINTAINER YourSelf

# Exclude the NPM cache from the image
VOLUME /root/.npm

# Create the app directory
RUN mkdir -p /usr/src/app
WORKDIR /usr/src/app

# Copy npm config
COPY .npmrc /root/.npmrc

# Install app
ONBUILD COPY package.json /usr/src/app/
ONBUILD RUN npm install
ONBUILD COPY . /usr/src/app

# Run
CMD [ "npm", "start" ]
  1. 制作所有节点。js/io.js 容器FROM you/iojs,一切顺利。

对于那些通过 google 找到这篇文章并且仍在寻找不涉及在 docker 图像和容器上留下私有 npm 令牌的替代方法的人:

我们能够通过在 docker build 之前执行 npm install 来实现此功能(通过这样做,您可以让 .npmrc 在 image\container 之外).在本地安装私有模块后,您可以将文件作为构建的一部分复制到映像中:

    # Make sure the node_modules contain only the production modules when building this image
    COPY . /usr/src/app

您还需要确保您的 .dockerignore 文件不排除 node_modules 文件夹。

将文件夹复制到图像中后,诀窍是 npm rebuild 而不是 npm install。这将重建任何受构建服务器和 docker OS:

之间的任何差异影响的本机依赖项
    FROM nodesource/vivid:LTS

    # For application location, default from nodesource is /usr/src/app
    # Make sure the node_modules contain only the production modules when building this image
    COPY . /usr/src/app
    WORKDIR /usr/src/app
    RUN npm rebuild
    CMD npm start

2020 年我们推出了 BuildKit。您不必再通过 COPYENV 传递秘密,因为它不被认为是安全的。

样本Dockerfile

# syntax=docker/dockerfile:experimental
FROM node:13-alpine

WORKDIR /app

COPY package.json yarn.lock ./

RUN --mount=type=ssh --mount=type=secret,id=npmrc,dst=$HOME/.npmrc \
  yarn install --production --ignore-optional --frozen-lockfile

# More stuff...

然后,您的构建命令可能如下所示:

docker build --no-cache --progress=plain --secret id=npmrc,src=/path-to/.npmrc .

有关更多详细信息,请查看:https://docs.docker.com/develop/develop-images/build_enhancements/#new-docker-build-secret-information

我建议不要使用 .npmrc 文件,而是使用 npm config set。这很有魅力,而且更干净:

ARG AUTH_TOKEN_PRIVATE_REGISTRY

FROM node:latest

ARG AUTH_TOKEN_PRIVATE_REGISTRY
ENV AUTH_TOKEN_PRIVATE_REGISTRY=${AUTH_TOKEN_PRIVATE_REGISTRY}

WORKDIR /home/usr/app

RUN npm config set @my-scope:registry https://my.private.registry && npm config set '//my.private.registry/:_authToken' ${AUTH_TOKEN_PRIVATE_REGISTRY}

RUN npm ci

CMD ["bash"]

buildkit 的答案是正确的,除了它以 root 身份运行所有内容,这被认为是一种糟糕的安全做法。

这是一个 Dockerfile,它在设置节点 Dockerfile 时使用正确的用户 node。请注意,秘密挂载设置了 uid 参数,否则它将作为 root 用户挂载,用户 node 无法读取。还要注意 node:node

user:group 的正确 COPY 命令
FROM node:12-alpine

USER node

WORKDIR /home/node/app

COPY --chown=node:node package*.json ./

RUN --mount=type=secret,id=npm,target=./.npmrc,uid=1000 npm ci

COPY --chown=node:node index.js .

COPY --chown=node:node src ./src

CMD [ "node", "index.js" ]