docker, nodejs: node not found error

Viewed 14490

(on Ubuntu 16.04 and Docker 1.13)

When I run my dockerfile that tries to run my server.js, I get an error:

sh: 1: node: not found

I did some research and the name node and nodejs got changed because of package conflicts and is causing the error; however, when I switch to nodejs-legacy is doesn't work. What is causing the issue?

error with nodejs

error with nodejs-legacy


DockerFile

FROM ubuntu
RUN apt-get update
RUN apt-get install nodejs -y 
#RUN rm -f package-lock.json
RUN apt-get install npm -y
RUN apt-get install apt-utils -y

WORKDIR /usr/scr/app

COPY package.json package-lock.json /usr/src/app/
COPY . .

EXPOSE 8080
CMD ["npm", "start"]

package.json

{
 "name": "iam",
 "version": "1.0.2",
 "description": "Identity and access management.",
 "main": "server.js", 
 "scripts": {"start": "node server.js" },
 "author": "",
 "license": "ISC",

 "dependencies": {
    "body-parser": "^1.17.2",
    "cors": "^2.8.3",
    "express": "^4.15.3",
    "jsonwebtoken": "^7.4.1",
    "ldapjs": "^1.0.1"
  }
}
5 Answers

Make sure to have a comma in between the CMD command array

CMD ["node", "server.js"] 

instead of

CMD ["node" "server.js"] 

Apparently the CMD should be JSON. I had

['node', 'app.js']

Meanwhile it should be

["node", "app.js"]

Change: Use double string quotes

You need to manually add a new symlink, which will point to nodejs. Example (please check the nodejs route, /usr/bin/nodejs is the default):

sudo ln -s /usr/bin/nodejs /usr/bin/node

@cassini is on the right track, but I don't think you've given enough information for us to track down exactly what the problem is. There's clearly something wrong with the way node.js has been installed from the Ubuntu repository. In fact, I would recommend not using the Ubuntu repository at all to install node.js - it usually serves pretty old versions of packages and the whole node/nodejs package naming problem is pretty confusing. Neither of these comments are intended as knocks against Ubuntu: they serve old packages because they try to serve stable packages, and the naming problem arises because of problems out of their control.

A better solution than using the Ubuntu repository, in my opinion, is to use one of the official node images from the Docker repository. If you check out that link, you'll see they have a wide variety of versions and operating systems available. You could rewrite your Dockerfile to look something like this:

# the Debian wheezy image with node 8.5.0 installed
FROM node:8.5.0-wheezy

# looks like you have a typo here... changed /usr/scr/app to /usr/src/app
WORKDIR /usr/src/app

COPY package.json package-lock.json /usr/src/app/
COPY . .

EXPOSE 8080
CMD ["npm", "start"]

As an aside... the Alpine linux images are nice if you want a small image. The Ubuntu image is going to be several hundred megabytes in size while the Alpine image will be significantly smaller. The downside is that it's not Debian based so there are a few quirks that you'll have to get used to.

If, however, you really want to go ahead with your own Ubuntu-based image with node.js I would first look at installing node.js directly from the source. This will involve downloading via wget/curl in your Dockerfile, unpacking it, and ensuring it's installed in the right place.

If you really want to use Ubuntu and the version from the repository, then you need to figure out what's wrong with the image you built. That means diving into a container running this image & finding the node binary.

To get shell access to the container:

docker run -it --rm <image name or hash> /bin/bash

Once you run this command on your host, you will be presented with a new bash shell prompt. Congratulations! You now have shell access to a temporary container based on your image. Now you need to poke around and see if you can run or find that binary.

Try node --version or nodejs --version to see if you have it installed. If that works, try which node or which nodejs to find the path to the binary.

If you can find the binary, you can edit your Dockerfile to include a link from somewhere in your path to that binary. For example, assuming which nodejs gives you /usr/bin/nodejs, you can use the link suggested by @cassini in your Dockerfile:

RUN ln -s /usr/bin/nodejs /usr/bin/node

I was just doing

CMD ["node": "server.js"] 

and trying for more than 4 hours finally I solved with this

CMD ["node", "server.js"] 

Actually this one comma means a lot

Related