有没有一种简单的方法可以在 Bitbucket Pipelines Docker 容器中更改为非 root 用户?

Is there an easy way to change to a non-root user in Bitbucket Pipelines Docker container?

Bitbucket Pipelines 使用 Docker 个容器来执行任务,默认情况下 Docker 个容器 运行 作为 root。这是 NPM 生命周期脚本的一个问题,因为 NPM 在 运行s 脚本时试图降级它的权限。

执行 postinstall 脚本时,NPM throws an errorcannot run in wd %s %s (wd=%s)。最简单的解决方案是 运行 npm install 带有 --unsafe-perm 标志,但我不喜欢这种方法。

Docker 的 best practices 写 Docker 文件指出:

If a service can run without privileges, use USER to change to a non-root user.

配置典型的 Docker 容器时,我会创建一个新的非根用户,并 运行 我的 npm 脚本作为该用户。

阅读 Pipelines documentation 后,我找不到任何与 Docker 的 USER 命令等效的命令。 我也许可以使用 useraddchownsu(尚未测试)但是有更简单的解决方案吗?

不幸的是,将 useraddchownsu 添加到 bitbucket-pipelines.yml 脚本部分会破坏管道并导致 repo:push webhook 失败。

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>)."
}

这个问题有两点要解决。


对于 运行 作为 Bitbucket Pipelines 中的非根用户,您可以完全按照您的建议执行并使用 USER Docker 命令。 node:6.2 图像不会映射到非 root 用户,因此如果您愿意,可以使用以下 Docker 文件创建一个新的 Docker 图像:

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。它似乎在没有 chown 的情况下也能正常工作。最后,我有一个看起来像这样的脚本 - 它看起来很好:

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 用户帐户,前提是它尚未包含在图像中,并使用 gosu 实用程序将其设置为执行的命令。

管道的 build 步骤已经在 $BUILD_DIR 上设置 chmod 777,因此不需要额外的 chown

因此,要能够在 Bitbucket Pipelines Docker 容器中更改为非根用户,您必须:

  1. 向您的存储库添加一个额外的 shell 脚本来安装 gosu 实用程序(它也可以作为 Pipelies 配置中的一个步骤直接包含)
  2. 调用 install-gosu.sh 脚本作为管道配置的第一步,
  3. id -u {user} &>/dev/null || useradd ...,
  4. 创建一个非root用户(先检查它是否已经存在)
  5. 以非 root 用户身份使用 gosu 运行 命令。

安装-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-pipelines.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

这很容易适用于其他 languages/users/commands。只需将 node 用户和 npm 命令交换为您需要的任何内容即可。

我用 nodejspython 图像测试了这个方法。