[英]How to keep node_modules inside container while using docker-compose and a non-root user?
[英]Is there an easy way to change to a non-root user in Bitbucket Pipelines Docker container?
Bitbucket Pipelines使用Docker容器來執行任務,默認情況下Docker容器以root身份運行。 這是NPM生命周期腳本的問題,因為NPM在運行腳本時嘗試降級其權限。
執行postinstall
腳本時, NPM會拋出一個 cannot run in wd %s %s (wd=%s)
的錯誤 。 最簡單的解決方案是使用--unsafe-perm
標志運行npm install,但我不喜歡這種方法。
Docker編寫Dockerfiles的最佳實踐表明:
如果服務可以在沒有權限的情況下運行,請使用USER更改為非root用戶。
配置典型的Docker容器時,我會創建一個新的非root用戶並以此用戶身份運行我的npm腳本。
閱讀Pipelines文檔后,我找不到任何與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管道中以非root用戶身份運行,您可以完全按照建議操作並使用USER Docker命令。 節點: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"
由於節點映像已經創建了一個節點用戶(至少在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實用程序為執行的命令設置它。
Pipelines的build
步驟已經在$BUILD_DIR
上設置chmod 777
,因此不需要額外的chown
。
因此,為了能夠在Bitbucket Pipelines Docker容器中更改為非root用戶,您必須:
install-gosu.sh
腳本作為Pipelines配置的第一步, id -u {user} &>/dev/null || useradd ...
創建一個非root用戶(檢查它是否已經存在) id -u {user} &>/dev/null || useradd ...
, 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
user和npm
命令交換到您需要的任何內容即可。
我用nodejs
和python
圖像測試了這個方法。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.