[英]npm install fails in jenkins pipeline in docker
我正在关注关于 Jenkins 管道的教程,我可以在节点 6.10 docker 容器下获得一个“hello world”。
但是,当我将默认的 EmberJS 应用程序(使用ember init
)添加到存储库并尝试在管道中构建它时,运行 npm install 时它会失败(因为目录访问问题)。 Jenkinsfile 可以在这里看到: https ://github.com/CloudTrap/pipeline-tutorial/blob/fix-build/Jenkinsfile
构建打印的错误消息是(在本地安装并在 Macbook 上使用java -jar jenkins.war
运行,不相关但以防万一)是:
npm ERR! Linux 4.9.12-moby
npm ERR! argv "/usr/local/bin/node" "/usr/local/bin/npm" "install"
npm ERR! node v6.10.0
npm ERR! npm v3.10.10
npm ERR! path /.npm
npm ERR! code EACCES
npm ERR! errno -13
npm ERR! syscall mkdir
npm ERR! Error: EACCES: permission denied, mkdir '/.npm'
npm ERR! at Error (native)
npm ERR! { Error: EACCES: permission denied, mkdir '/.npm'
npm ERR! at Error (native)
npm ERR! errno: -13,
npm ERR! code: 'EACCES',
npm ERR! syscall: 'mkdir',
npm ERR! path: '/.npm',
npm ERR! parent: 'pipeline-tutorial' }
npm ERR!
npm ERR! Please try running this command again as root/Administrator.
注意:我不想以 root / sudo 身份运行npm install
。
更新:我已经取得了一些进展,如下所示:
我从日志中找到了 Jenkins 使用容器构建的命令:
[Pipeline] withDockerContainer
$ docker run -t -d -u 501:20 -w /long-workspace-directory -v /long-workspace-directory:/long-workspace-directory:rw -v /long-workspace-directory@tmp:/long-workspace-directory@tmp:rw -e
因此,当 docker 映像运行时,它的工作目录是/long-workspace-directory
(它实际上是一个看起来很神秘的 jenkins 工作区路径),用户 id 是 501(组 id 20)等。用户没有名字(这显然破坏了与这个问题无关的其他事情)。
更改代理以使用 Dockefile:
agent { dockerfile { filename 'Dockerfile' args '-v /.cache/ -v /.bower/ -v /.config/configstore/' } }
指定args '-v ...'
为 npm install / bower 需要的目录创建卷。
添加环境并将主页设置为“。” 解决这个问题如下。
pipeline {
agent { docker { image 'node:8.12.0' } }
environment {
HOME = '.'
}
stages {
stage('Clone') {
steps {
git branch: 'master',
credentialsId: '121231k3jkj2kjkjk',
url: 'https://myserver.com/my-repo.git'
}
}
stage('Build') {
steps {
sh "npm install"
}
}
}
}
来自https://github.com/jenkins-infra/jenkins.io/blob/master/Jenkinsfile
docker.image('openjdk:8').inside {
/* One Weird Trick(tm) to allow git(1) to clone inside of a
* container
*/
withEnv([
/* Override the npm cache directory to avoid: EACCES: permission denied, mkdir '/.npm' */
'npm_config_cache=npm-cache',
/* set home to our current directory because other bower
* nonsense breaks with HOME=/, e.g.:
* EACCES: permission denied, mkdir '/.config'
*/
'HOME=.',
]) {
// your code
}
}
在这个问题上浪费了一整天,我发现只需在代理阶段使用管道编辑器添加以下内容作为环境变量就可以解决问题。
'npm_config_cache=npm-cache'
当 Jenkins 在 Docker 代理中运行阶段时,它通常设置HOME=/
(图像WORKDIR
值),但是 Jenkins 用户在该目录中没有写入权限,这就是npm
无法创建其缓存目录~/.npm
的原因。 要解决这个问题,您需要覆盖HOME
或 NPM 默认缓存目录:
pipeline {
agent {
docker {
reuseNode true
image 'node:16.15'
}
}
environment {
// Override HOME to WORKSPACE
HOME = "${WORKSPACE}"
// or override default cache directory (~/.npm)
NPM_CONFIG_CACHE = "${WORKSPACE}/.npm"
}
stages {
stage('Build') {
steps {
sh 'npm install'
sh 'npm run build'
}
}
}
}
只想提供更多细节,简而言之,接受的答案有效,但我是 Docker 新手,想要更好地理解并想分享我发现的东西。
所以对于我们的詹金斯设置,它通过以下方式启动容器
docker run -t -d -u 995:315 -w /folder/forProject -v /folder/forProject:/folder/forProject:rw,z ...
结果,该容器以用户身份运行uid=995 gid=315 groups=315
由于我使用的映像 (circleci/node:latest) 没有具有此 UID/GID 的用户,因此该用户将没有“主”文件夹,并且仅对已安装的卷具有权限。
当调用 NPM 命令时,它将尝试使用该用户的主目录(用于缓存),并且由于该用户不是在映像上创建的,因此主目录设置为/
(Linux 的默认值?)。 因此,为了让 NPM 正常工作,我们只需通过 Jenkins 文件将用户的容器 HOME 环境变量指向当前文件夹
pipeline {
agent none
stages {
stage('NPM Installs') {
agent {
docker {
image 'circleci/node:latest'
}
}
environment { HOME="." }
...
}
}
}
从而使用户能够在/folder/forProject/.npm
中创建所需的.npm
文件夹
希望这对某人有帮助,如果您发现我做错了什么,请告诉我:D
我添加了同样的问题。 我使用root
用户运行Docker镜像解决了它:
node {
stage("Prepare environment") {
checkout scm
// Build the Docker image from the Dockerfile located at the root of the project
docker.build("${JOB_NAME}")
}
stage("Install dependencies") {
// Run the container as `root` user
// Note: you can run any official Docker image here
withDockerContainer(args: "-u root", image: "${JOB_NAME}") {
sh "npm install"
}
}
}
您可以覆盖 Jenkins 运行 docker 容器的用户,例如这里我用 root 覆盖(userid:groupid 为 0:0):
docker {
image 'node:8'
args '-u 0:0'
}
您可以在控制台输出的docker run
参数中发现当前用户。
我们有同样的问题,对我们来说问题的核心是,容器中的用户和运行 Jenkins 节点的用户有不同的 UID。 在更改容器中用户的 UID+GID(并更改用户主目录的所有权)以匹配运行构建节点的用户之后,npm 将表现正常。
如果容器用户的主目录不可写,也可能发生这种情况。
Dockerfile 中的代码:
RUN usermod -u <uid of buildnode> <container user> && \
groupmod -g <gid of buildnode> <container user group> && \
chown -R <container user>:<container user group> /home/<container user>
由于 Workspace 已安装到容器中,因此它已经属于 UID。 当通过 Jenkinsfile 运行容器时,容器用户的 UID 和 GID 会自动设置为与 buildnode 匹配。 但主目录仍将拥有其原始所有者。
现在 node_modules 将被放置在当前目录中。
就我而言,问题是在容器内我是用户 jenkins 而不是 root。 我通过在容器内设置whoami
到达那里并得到了cannot determine user 111
(恰好是詹金斯)之类的错误。 所以我做了以下事情:
stage('Run build') {
webappImage.inside("-u root") {
sh "yarn run build"
}
}
这个配置对我有用。
pipeline {
agent {
docker {
image 'node:6-alpine'
args '-p 3000:3000 -p 5000:5000'
args '-u 0:0'
}
}
environment {
CI = 'true'
}
stages {
stage('Build') {
steps {
sh 'npm install --unsafe-perm'
}
}
stage('Test') {
steps {
sh './jenkins/scripts/test.sh'
}
}
stage('Deliver for development') {
when {
branch 'development'
}
steps {
sh './jenkins/scripts/deliver-for-development.sh'
input message: 'Finished using the web site? (Click "Proceed" to continue)'
sh './jenkins/scripts/kill.sh'
}
}
stage('Deploy for production') {
when {
branch 'production'
}
steps {
sh './jenkins/scripts/deploy-for-production.sh'
input message: 'Finished using the web site? (Click "Proceed" to continue)'
sh './jenkins/scripts/kill.sh'
}
}
}
}
就我而言,这解决了问题
agent {
docker {
image 'node:10-stretch'
args '-v /home/jenkins/.ssh:/home/jenkins/.ssh:ro -u 0'
}
}
我正在使用 maven 构建项目,它确实正在运行负责调用 npm install 的前端 maven-plugin 所以 npm install 因错误而中断:path /.npm npm ERR! 代码 EACCES npm 错误! errno -13 npm 错误! 系统调用 mkdir
我将其更改为npm install --cache /tmp/empty-cache
它奏效了
您可以在构建之前即时安装nvm
,在具有NVM_DIR
的本地目录中,无需将其设置为全局依赖项:
mkdir -p node_dir
export NVM_DIR=$(pwd)/node_dir
curl https://raw.githubusercontent.com/creationix/nvm/v0.33.1/install.sh | bash
source $(pwd)/node_dir/nvm.sh
nvm install 7
nvm use 7
新地点是:
$ which node
~/someDir/node_dir/versions/node/v7.7.2/bin/node
$ which npm
~/someDir/node_dir/versions/node/v7.7.2/bin/npm
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.