Есть ли простой способ перейти на пользователя без root в контейнере Докера Bitbucket Pipelines?

Bitbucket Трубопроводов использует контейнеры Docker для выполнения задач и по умолчанию контейнеры Docker выполняются как root. Это проблема для сценариев жизненного цикла NPM, поскольку NPM пытается понизить свои привилегии при запуске сценариев.

при выполнении postinstall скрипт NPM выдает ошибку что это cannot run in wd %s %s (wd=%s). Самое простое решение-запустить установку npm с помощью --unsafe-perm флаг, но мне не нравится такой подход.

настройки в лучшие практики для написания Dockerfiles говорится, что:

если служба может работать без привилегий, используйте USER для изменения на не-root пользователей.

при настройке обычного контейнера Docker я бы создал нового пользователя, не являющегося root, и запустил бы мои сценарии npm от имени этого пользователя.

после прочтения документация по трубопроводам я не смог найти эквивалента команде пользователя Docker. я мог бы использовать useradd, chown и su (еще не проверял), но есть ли более простое решение?

к сожалению добавлять useradd, chown и su to bitbucket-pipelines.yml раздел скрипта разрывает конвейеры и приводит к сбою repo:push веб-перехватчик.

image: node:6.2

pipelines:
  default:
    - step:
        script:
          - useradd --user-group --create-home --shell /bin/false node
          - chown -R node: /opt/atlassian/bitbucketci/agent/build
          - su -s /bin/sh -c "npm install" node
          - su -s /bin/sh -c "npm run test:coverage --silent" node

трубопроводы отвечает

{
  "code": 500,
  "message": "There was an error processing your request. It has been logged (ID <removed>)."
}

3 ответов


есть две вещи, чтобы обратиться в этом вопросе.


чтобы работать как пользователь без root в конвейерах Bitbucket, вы можете сделать именно то, что вы предложили, и использовать команду User Docker. Узел: 6.2 изображение не сопоставляется с пользователем без root, поэтому, если вы хотите сделать это, вы можете создать новый образ Docker со следующим файлом Dockerfile:

FROM node:6.2

USER foo

ошибка 500, которую вы получаете, похоже, является проблемой с разбором YAML на этом строка:

- chown -R node: /opt/atlassian/bitbucketci/agent/build

': '- специальный символ в формате YAML. Указание пары ключ-значение. Чтобы исправить это, поместите содержимое этой строки внутри кавычек вместо этого следующим образом:

- "chown -R node: /opt/atlassian/bitbucketci/agent/build"

Я бы также предложил вам использовать новую переменную среды по умолчанию для пути сборки. $BITBUCKET_CLONE_DIR. Поэтому измените строку на

- "chown -R node: $BITBUCKET_CLONE_DIR"

поскольку образ узла уже создает пользователя узла (по крайней мере, в 6.9+), вам не нужно useradd. Кажется, он хорошо работает и без чауна. В конце концов, у меня есть скрипт, выглядящий так - и он кажется просто прекрасным:

image: node:7

pipelines:
  default:
    - step:
        script:
          - su -s /bin/bash -c "npm install" node
          - su -s /bin/bash -c "npm run build" node

самое удобное решение, которое я нашел, - создать учетную запись пользователя без root, только если она еще не включена в изображение и использовать госу утилита для установки его для выполняемых команд.

трубопроводы' build шаг уже устанавливает chmod 777 на $BUILD_DIR дополнительные chown не требуется.

Итак, чтобы иметь возможность перейти на пользователя без root в контейнере Докера Bitbucket Pipelines, вам нужно:

  1. добавить дополнительный сценарий оболочки для вашего репозитория, который устанавливает утилиту gosu (она также может быть включена непосредственно в качестве шага в конфигурации Pipelies)
  2. вызов install-gosu.sh скрипт как первый шаг в конфигурации конвейеров,
  3. создайте пользователя, не являющегося root (сначала проверьте, существует ли он) с помощью id -u {user} &>/dev/null || useradd ...,
  4. используйте gosu для запуска команд как не-root пользователь.

install-gosu.sh

#!/bin/bash

GOSU_VERSION=1.10
GNUPGHOME="$(mktemp -d)"

set -x

apt-get update && apt-get install -y --no-install-recommends ca-certificates wget && rm -rf /var/lib/apt/lists/* \
&& dpkgArch="$(dpkg --print-architecture | awk -F- '{ print $NF }')" \
&& wget -O /usr/local/bin/gosu "https://github.com/tianon/gosu/releases/download/$GOSU_VERSION/gosu-$dpkgArch" \
&& wget -O /usr/local/bin/gosu.asc "https://github.com/tianon/gosu/releases/download/$GOSU_VERSION/gosu-$dpkgArch.asc" \
&& gpg --keyserver ha.pool.sks-keyservers.net --recv-keys B42F6819007F00F88E364FD4036A9C25BF357DD4 \
&& gpg --batch --verify /usr/local/bin/gosu.asc /usr/local/bin/gosu \
&& rm -r "$GNUPGHOME" /usr/local/bin/gosu.asc \
&& chmod +x /usr/local/bin/gosu \
&& gosu nobody true \
&& apt-get purge -y --auto-remove ca-certificates wget

bitbucket-трубопроводы.в формате YML

image: node:6

pipelines:
  default:
    - step:
        script:
          - bash $BITBUCKET_CLONE_DIR/install-gosu.sh
          - id -u node &>/dev/null || useradd --user-group --create-home --shell /bin/false node
          - gosu node npm install
          - gosu node npm test

это можно легко приспособиться для других языков / потребителей / команд. Просто замените node пользователь и npm команды все, что вам нужно.

я протестировал этот метод с nodejs и python картинки.