Simple CircleCI 2.0 configuration fails for global NPM package installation
tldr - use the following prefix:
npm install --prefix=$HOME/.local --global serverless
- Replace
serverless
with your own global package requirements.
Background:
- After a bit of experimentation the above seems to be the cleanest way I've found.
CircleCI's current
circleci/node:lts-buster
image has the following on the path:/home/circleci/.local/bin:/home/circleci/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin
I was unable to write to
/home/circleci/bin
due to blocked write permissions.- I was able to write to
/home/circleci/.local/bin
- Adding the
--prefix=$HOME/.local
option tonpm install
command means the global package is then installed into/home/circleci/.local/bin
- After install, the command, in my case
serverless
, is executable.
As said the Dockerfile from the top is not fully identical with the one in the CircleCI-config. In the Dockerfile the base image is node
which by default runs under the root
user.
The circleci/node
image on the on the other hand drops to the unprivileged circleci
user. So a 100% identical Dockerfile based on the node
image would look like this:
FROM node:10
RUN useradd -m circleci
USER circleci
RUN npm set unsafe-perm true
RUN npm install -g '@oresoftware/[email protected]'
And with this Dockerfile the same error appears as in CircleCI.
One solution would be to use sudo
, the problem with this is that you would have to use sudo
on every command which makes use of the node package you installed (since with sudo it would actually be installed in the /root
directory which is not accessible with the circleci
user).
I think the better option would be to install the package in the circleci
home directory.
{
"version": 2,
"jobs": {
"build": {
"docker": [
{
"image": "circleci/node:10"
}
],
"steps": [
{
"run": "npm set prefix=/home/circleci/npm && echo 'export PATH=$HOME/circleci/npm/bin:$PATH' >> /home/circleci/.bashrc"
},
{
"run": "npm install -g --loglevel=warn '@oresoftware/[email protected]'"
}
]
}
}
}
This way you don't have to sudo
everytime you want to use the package.
On CircleCI you'd need to use sudo
. The default user is circleci
which has passwordless sudo access.