10

Bitbucket Pipelines使用 Docker 容器来执行任务,默认情况下 Docker 容器以 root 身份运行。这对于 NPM 的生命周期脚本来说是一个问题,因为 NPM 在运行脚本时会尝试降级其权限。

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

Docker 编写 Dockerfiles 的最佳实践指出:

如果服务可以在没有特权的情况下运行,请使用 USER 更改为非 root 用户。

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

在阅读Pipelines 文档后,我找不到任何与 Docker 的 USER 命令等效的东西。我也许可以使用useradd, chownand su(还没有测试)但是有没有更简单的解决方案?

不幸的是,将useradd,chown和添加subitbucket-pipelines.yml脚本部分会破坏管道并导致repo:pushwebhook 失败。

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

3 回答 3

3

这个问题有两点需要解决。


要在 Bitbucket Pipelines 中以非 root 用户身份运行,您可以完全按照您的建议执行操作并使用 USER Docker 命令。node:6.2 镜像不会映射到非 root 用户,因此如果您愿意,可以使用以下 Dockerfile 创建一个新的 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"
于 2016-10-12T13:37:52.280 回答
2

由于节点映像已经创建了一个节点用户(至少在 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
于 2017-01-05T08:07:45.137 回答
0

The most comfortable solution I've found is to create a non-root user account only if it's not already included in the image and use the gosu utility to set it for executed commands.

Pipelines' build step is already setting the chmod 777 on the $BUILD_DIR so additional chown is not required.

So, to be able to change to a non-root user in Bitbucket Pipelines Docker container you have to:

  1. add an additional shell script to your repository that installs the gosu utility (it can also be included directly as a step in Pipelies config)
  2. call the install-gosu.sh script as the first step in Pipelines config,
  3. create a non-root user (checking whether it already exists first) with id -u {user} &>/dev/null || useradd ...,
  4. use gosu to run commands as a non-root user.

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-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

This can easily be adapted for other languages/users/commands. Just swap the node user and npm commands to whatever you need.

I've tested this method with nodejs and python images.

于 2017-03-23T23:05:55.593 回答