Сборка докера + приватный NPM (+ приватный концентратор докеров)
У меня есть приложение, которое работает в контейнере Docker. Для этого требуются некоторые частные модули из частного реестра NPM компании (Sinopia), а для доступа к ним требуется аутентификация пользователя. Dockerfile - это FROM iojs:latest
,
Я пытался:
1) создание файла.npmrc в корне проекта, на самом деле это не имеет значения, и npm, кажется, игнорирует его 2) использование переменных env для NPM_CONFIG_REGISTRY
, NPM_CONFIG_USER
и т.д., но пользователь не авторизуется.
По сути, у меня, похоже, нет способа аутентификации пользователя в docker build
процесс. Я надеялся, что кто-то уже мог столкнуться с этой проблемой (кажется достаточно очевидной проблемой) и найдет хороший способ ее решения.
(В довершение всего, я использую Automated Builds на Docker Hub (запускается при нажатии), чтобы наши серверы могли получить доступ к частному реестру Docker с помощью предварительно собранных образов.)
Есть ли хорошие способы: 1) ввести учетные данные для NPM во время сборки (чтобы мне не нужно было вводить учетные данные в мой Dockerfile) ИЛИ 2) сделать это другим способом, о котором я не думал?
7 ответов
Я нашел несколько элегантное решение в создании базового образа для ваших контейнеров node.js / io.js (you/iojs
):
- войдите в свой личный реестр npm с пользователем, которого вы хотите использовать для Docker
- скопировать
.npmrc
файл, который это генерирует
пример .npmrc
:
registry=https://npm.mydomain.com/
username=dockerUser
email=docker@mydomain.com
strict-ssl=false
always-auth=true
//npm.mydomain.com/:_authToken="someAuthToken"
- создать
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" ]
- Сделайте все ваши контейнеры node.js / io.js
FROM you/iojs
и ты в порядке.
В 2020 году у нас появился BuildKit. Вам не нужно передавать секреты через
COPY
или же
ENV
больше, так как это небезопасно.
Образец
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
Для тех, кто находит эту статью через Google и все еще ищет альтернативный способ, который не предполагает оставления вам приватных токенов npm на изображениях и контейнерах докера:
Мы смогли заставить это работать, выполнив npm install
до docker build
(Делая это, он позволяет вам иметь .npmrc
за пределами вашего изображения \ контейнера). После того, как частные модули были установлены локально, вы можете скопировать ваши файлы в образ как часть вашей сборки:
# 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
, Это восстановит любые собственные зависимости, на которые влияют различия между вашим сервером сборки и операционной системой докера:
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
Ответ buildkit правильный, за исключением того, что он запускает все как root, что считается плохой практикой безопасности.
Вот Dockerfile, который работает и использует правильного пользователя в качестве узла, установленного Dockerfile. Обратите внимание, что секретное крепление имеет
uid
набор параметров, в противном случае он монтируется как root, какой пользователь
node
не могу читать. Обратите также внимание на правильные команды COPY, которые
user:group
из
node:node
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" ]
Я бы рекомендовал не использовать
.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"]
@paul-s Должен быть принятый ответ сейчас, потому что он более свежий, ИМО. В качестве дополнения вы упомянули, что используетеdocker/build-push-action
действие, поэтому ваш рабочий процесс должен быть следующим:
- uses: docker/build-push-action@v3
with:
context: .
# ... all other config inputs
secret-files: |
NPM_CREDENTIALS=./.npmrc
А потом, конечно, привязать.npmrc
файл из вашего dockerfile, используя указанный вами идентификатор. В моем случае я использую образ на основе Debian (uid начинается с 1000). В любом случае:
RUN --mount=type=secret,id=NPM_CREDENTIALS,target=<container-workdir>/.npmrc,uid=1000 \
npm install --only=production
Для будущих людей, которые могут попытаться решить проблему сбоя установки в своей настройке: не забудьте скопировать.npmrc
файл, если вы полагаетесь на него для разрешения зависимостей:
COPY .npmrc ./