Skip to content
Advertisement

Team City “minimal build agent” Docker image – “npm: not found” Linux issue?

First of all, I think this is more of a Linux issue as the problem seems to be on a linux-flavoured Docker container, but I’m happy to accept that I can do something to the team city config to overcome this.

I’m also not very experienced with Linux, Docker or node/npm, though I do have a lot of development experience and am very comfortable with command line interfaces in general.

Background

We currently have Team City set up as a build server, for building a variety of projects:

  • .Net Framework,
  • .Net Core
  • Angular CLI
  • A couple of simple websites which use node packages to generate HTML from Markdown.

The server is running as a Docker container using Docker for Windows on a Windows Server box, and this is working well.
We have one Windows 10 Build agent (a VM) which is also working fine, and builds all the .Net and .Net Core stuff fine.

The simple docs site stuff primarily uses the markdown-to-html node package, so its build steps simply get all the source .md files and compile to html with markdown-to-html, plus use some other npm packages for SASS compilation and minification of js etc. No actual node code as such, just some jQuery. In order to not tie up the other agent, and because this stuff can run happily on Linux, I want to have this running on a small docker image rather than a full VM build agent somewhere.

I previously successfully used a node.js team city agent docker image (either jacobpeddk/teamcity-agent-nodejs or omez/teamcity-agent-nodejs – can’t recall) which did work for a time, though I had issues with being able to install some npm packages globally in build scripts, which meant I had to get a bash terminal into the container and run some manual npm commands. I also I think had to run apt-get install zip to get a zipping step to work. This worked fine for a while (weeks).

I added some extra JS stuff to one of these simple projects, and suddenly I was getting errors when trying to build. I (perhaps stupidly) decided that this was probably due to the container having older versions of node and/or npm etc, so I attempted to update this by getting a bash shell into the container, installing nvm and updating node.js & npm.

This ended up with a rather broken container (node errors), so I thought I’d instead start again, but actually start with the jetbrains/minimal-build-agent Docker image instead, with the aim of ending up with a nice bespoke image for our needs specifically (as I couldn’t find a very up-to-date pre-existing one)

I’ve running a Bash shell directly on the build agent container by executing this on the host:

docker exec -it basicagent /bin/bash

then from there I’ve installed nvm, Python (required for node install step) and node:

  • 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 (matching version on my dev machine)
  • npm install -g markdown-folder-to-html (npm package I previously found I had to install globally)
  • apt-get install zip (just used for a build step to zip up artifacts)

If I now run (via the bash shell) npm -version I get back 5.6.

If I try to get a build to run that uses npm in a command line step, then I get this error in the build log: /opt/buildagent/temp/agentTmp/custom_script2764770419520852926: npm: not found

I wondered if it was an issue with the user/path that the team city agent process is using vs. the one I’m using in Bash, so I added the following to the build script:

echo PATH = $PATH
echo user var = $USER
echo user via 'id':
id -u -n

the output of which is:

PATH = /usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin
user var =
user via id:
root

So it’s running the agent as root, and doesn’t appear to have node in the $PATH at all.

If I run the above directly from Bash however, I can see that I am root, but my $PATH is different:

PATH = /root/.nvm/versions/node/v8.11.1/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin

root

So I’m now confused: I’ve re-started the container and this has had no effect – it seems that when I’m logged in as root manually I have a certain path set, but when the build agent service is running as root it’s different.

Advertisement

Answer

I have no idea why this happens, but I’ve basically worked around the problem by adding: export PATH=$PATH:/root/.nvm/versions/node/v8.11.1/bin

to the top of every build step that uses npm in a script. To my mind this seems a rather daft thing to have to do – considering this used to work without this, and the only real difference is possibly a slightly different flavour of linux container. AFAIK the original build agent container was based on the jetbrains minimal-build-agent one, so unless they’ve changed what they base that on it should be roughly the same…

I also had to change the compressor being used in a node-minify build step from gcc (google closure compiler) to babel-minify as the former was basically hanging indefinitely, but that is a separate problem (though also something that was fine and now isn’t…)

Thanks to anyone who took the time to read… though I do wonder if one-day I’ll exhaust my own research options, and finally go ask the internet and actually get someone respond – for some reason whenever I get to the point where I have to ask, it always seems no-one else has the answer either and I end up having to work it out myself. It’s probably character-building though I suppose.. (this isn’t just SO – I’ve found this be the case for over 15 years on various forums about various things…)

User contributions licensed under: CC BY-SA
7 People found this is helpful
Advertisement