linux - Team City“最小构建代理”Docker 映像 - “npm:未找到”Linux 问题?
问题描述
首先,我认为这更像是一个 Linux 问题,因为问题似乎出在 linux 风格的 Docker 容器上,但我很高兴接受我可以对团队城市配置做一些事情来克服这个问题。
我对 Linux、Docker 或 node/npm 也不是很有经验,尽管我确实有很多开发经验,并且通常对命令行界面非常熟悉。
背景
我们目前将 Team City 设置为构建服务器,用于构建各种项目:
- .Net 框架,
- .Net 核心
- 角 CLI
- 几个使用节点包从 Markdown 生成 HTML 的简单网站。
该服务器作为 Docker 容器在 Windows Server 机器上使用 Docker for Windows 运行,并且运行良好。
我们有一个 Windows 10 Build 代理(一个 VM),它也可以正常工作,并且可以很好地构建所有 .Net 和 .Net Core 的东西。
简单的 docs 站点主要使用 markdown-to-html 节点包,因此其构建步骤只需获取所有源 .md 文件并使用 markdown-to-html 编译为 html,并使用其他一些 npm 包进行 SASS 编译和缩小js 等。没有实际的节点代码,只有一些 jQuery。为了不占用其他代理,并且因为这些东西可以在 Linux 上愉快地运行,我想让它在一个小的 docker 映像上运行,而不是某个地方的完整 VM 构建代理。
我之前成功使用了一个 node.js 团队城市代理 docker 图像(jacobpeddk/teamcity-agent-nodejs
或者omez/teamcity-agent-nodejs
- 不记得),它确实工作了一段时间,尽管我无法在构建脚本中全局安装一些 npm 包,这意味着我有将 bash 终端放入容器并运行一些手动 npm 命令。我也认为必须跑步apt-get install zip
才能使压缩步骤起作用。这工作了一段时间(几周)。
我在其中一个简单的项目中添加了一些额外的 JS 内容,但在尝试构建时突然出现错误。我(也许愚蠢地)认为这可能是由于容器具有旧版本的 node 和/或 npm 等,所以我尝试通过将 bash shell 放入容器、安装 nvm 并更新 node.js 和 npm 来更新它。
这最终导致了一个相当损坏的容器(节点错误),所以我想我应该重新开始,但实际上是从jetbrains/minimal-build-agent
Docker 映像开始,目的是最终得到一个很好的定制映像,以满足我们的具体需求(因为我找不到一个非常最新的预先存在的)
我通过在主机上执行以下命令直接在构建代理容器上运行 Bash shell:
docker exec -it basicagent /bin/bash
然后从那里我安装了 nvm、Python(节点安装步骤所需)和节点:
curl -o- https://raw.githubusercontent.com/creationix/nvm/v0.33.2/install.sh | bash
export NVM_DIR="$HOME/.nvm"
[ -s "$NVM_DIR/nvm.sh" ] && \. "$NVM_DIR/nvm.sh" # This loads nvm
[ -s "$NVM_DIR/bash_completion" ] && \. "$NVM_DIR/bash_completion" # This loads nvm bash_completion
apt-get update
apt-get install python 3.6
nvm install v8.11.1
(我的开发机器上的匹配版本)npm install -g markdown-folder-to-html
(我以前发现我必须全局安装的 npm 包)apt-get install zip
(仅用于压缩工件的构建步骤)
如果我现在运行(通过 bash shell)npm -version
,我会返回 5.6。
如果我尝试在命令行步骤中运行使用 npm 的构建,则会在构建日志中收到此错误:
/opt/buildagent/temp/agentTmp/custom_script2764770419520852926: npm: not found
我想知道团队城市代理进程使用的用户/路径与我在 Bash 中使用的用户/路径是否存在问题,因此我在构建脚本中添加了以下内容:
echo PATH = $PATH
echo user var = $USER
echo user via 'id':
id -u -n
其输出是:
PATH = /usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin
user var =
user via id:
root
所以它以root身份运行代理,并且似乎在 $PATH 中根本没有节点。
但是,如果我直接从 Bash 运行上述内容,我可以看到我是 root,但我的 $PATH 不同:
PATH = /root/.nvm/versions/node/v8.11.1/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin
root
所以我现在很困惑:我已经重新启动了容器,但这没有任何效果 - 似乎当我以root身份手动登录时,我设置了某个路径,但是当构建代理服务以根不一样。
解决方案
我不知道为什么会发生这种情况,但我基本上通过添加以下内容解决了这个问题:
export PATH=$PATH:/root/.nvm/versions/node/v8.11.1/bin
在脚本中使用 npm的每个构建步骤的顶部。在我看来,这似乎是一件相当愚蠢的事情 - 考虑到这在没有这个的情况下曾经可以工作,唯一真正的区别可能是 linux 容器的风格略有不同。AFAIK最初的构建代理容器是基于jetbrains最小构建代理容器,所以除非他们改变了他们所基于的东西,否则应该大致相同......
我还必须将 node-minify 构建步骤中使用的压缩器从 gcc(谷歌闭包编译器)更改为 babel-minify,因为前者基本上无限期挂起,但这是一个单独的问题(尽管现在也很好)不是……)
感谢任何花时间阅读的人......虽然我确实想知道有一天我是否会用尽我自己的研究选项,最后去互联网上询问并真正得到某人的回应 - 出于某种原因,每当我谈到这一点时在我必须问的地方,似乎总是没有其他人有答案,我最终不得不自己解决。虽然我想这可能是性格塑造..(这不仅仅是这样 - 我在各种论坛上发现这种情况已经超过 15 年了......)
推荐阅读
- excel - VBA清除工作表并从其他工作表复制数据
- php - 来自根级文件夹的 php glob 图像
- python - 将 SQL 查询从 Python 导出到 txt 文件
- python-3.x - 如何在 matplotlib 中绘制数据框的多列
- javascript - Next.js grpc-node 使用
- excel - 将 2 个值与 3 个 if 条件进行比较
- android - 扑动 app_localization 崩溃
- regex - 动态变量名和哈希键
- google-cloud-platform - 如何将数据从 csv 导入 gcp 数据存储
- java - Spring Boot 微服务为 SOAP 服务提供 json 接口