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

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

当执行postinstall脚本时, NPM会抛出一个错误 ,它cannot run in wd %s %s (wd=%s) 。 最简单的解决scheme是使用--unsafe-perm标志运行npm install,但我不喜欢这种方法。

Docker写Dockerfiles的最佳实践指出:

如果一项服务可以运行没有权限,使用USER来更改为非root用户。

当configuration一个典型的Docker容器时,我将创build一个新的非root用户,并以该用户身份运行我的npm脚本。

在阅读Pipelines文档后,我找不到Docker的USER命令的任何等价物。 我可能能够使用useraddchownsu (还没有testing过),但有一个更简单的解决scheme吗?

不幸的是,添加useraddchownsubitbucket-pipelines.yml脚本部分中断pipe道并导致失败的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 

pipe道响应

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

在这个问题上有两件事需要解决。


要以Bitbucketpipe道中的非root用户身份运行,您可以完全按照您的build议进行操作,并使用USER Docker命令。 节点:6.2映像不映射到非root用户,所以如果你想这样做,你可以用下面的Dockerfile创build一个新的Docker映像:

 FROM node:6.2 USER foo 

您收到的500错误似乎是YAMLparsing在这一行上的问题:

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

':'是YAML格式的特殊字符。 指示键值对。 为了解决这个问题,把这个内容放在引号里面,像这样:

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

我也build议你现在使用新的默认环境variables的构buildpath。 $ BITBUCKET_CLONE_DIR。 所以改变线,而不是

 - "chown -R node: $BITBUCKET_CLONE_DIR" 

由于节点图像已经创build了一个节点用户(至less在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 

我find的最舒适的解决scheme是创build一个非root用户帐户,只要它不包含在图像中,并使用gosu实用程序为执行的命令设置。

pipe道的build步骤已经在$BUILD_DIR上设置了chmod 777 ,所以不需要额外的chown

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

  1. 添加一个额外的shell脚本到安装gosu工具的仓库(它也可以作为Pipeliesconfiguration中的一个步骤直接包含)
  2. 调用install-gosu.sh脚本作为Pipelinesconfiguration的第一步,
  3. id -u {user} &>/dev/null || useradd ...创build一个非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 

到位桶,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 

这可以很容易地适用于其他语言/用户/命令。 只需将node用户和npm命令交换到你需要的任何地方。

我已经用nodejspython图像testing了这个方法。