有没有一种简单的方法可以在 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 error 即 cannot 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 命令等效的命令。 我也许可以使用 useradd
、chown
和 su
(尚未测试)但是有更简单的解决方案吗?
不幸的是,将 useradd
、chown
和 su
添加到 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 容器中更改为非根用户,您必须:
- 向您的存储库添加一个额外的 shell 脚本来安装 gosu 实用程序(它也可以作为 Pipelies 配置中的一个步骤直接包含)
- 调用
install-gosu.sh
脚本作为管道配置的第一步,
- 用
id -u {user} &>/dev/null || useradd ...
, 创建一个非root用户(先检查它是否已经存在)
- 以非 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
命令交换为您需要的任何内容即可。
我用 nodejs
和 python
图像测试了这个方法。
Bitbucket Pipelines 使用 Docker 个容器来执行任务,默认情况下 Docker 个容器 运行 作为 root。这是 NPM 生命周期脚本的一个问题,因为 NPM 在 运行s 脚本时试图降级它的权限。
执行 postinstall
脚本时,NPM throws an error 即 cannot 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 命令等效的命令。 我也许可以使用 useradd
、chown
和 su
(尚未测试)但是有更简单的解决方案吗?
不幸的是,将 useradd
、chown
和 su
添加到 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 容器中更改为非根用户,您必须:
- 向您的存储库添加一个额外的 shell 脚本来安装 gosu 实用程序(它也可以作为 Pipelies 配置中的一个步骤直接包含)
- 调用
install-gosu.sh
脚本作为管道配置的第一步, - 用
id -u {user} &>/dev/null || useradd ...
, 创建一个非root用户(先检查它是否已经存在)
- 以非 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
命令交换为您需要的任何内容即可。
我用 nodejs
和 python
图像测试了这个方法。