有没有一种简单的方法在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命令的任何等价物。 我可能能够使用 useradd
, chown
和su
(还没有testing过),但有一个更简单的解决scheme吗?
不幸的是,添加useradd
, chown
和su
到bitbucket-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用户,您必须:
- 添加一个额外的shell脚本到安装gosu工具的仓库(它也可以作为Pipeliesconfiguration中的一个步骤直接包含)
- 调用
install-gosu.sh
脚本作为Pipelinesconfiguration的第一步, - 用
id -u {user} &>/dev/null || useradd ...
创build一个非root用户(检查它是否已经存在)id -u {user} &>/dev/null || useradd ...
, - 使用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
命令交换到你需要的任何地方。
我已经用nodejs
和python
图像testing了这个方法。