Why NPM is not available in Docker Conainter

I am very new to docker and playing with it. I am trying to run nodejs app in docker container. I took ubuntu:14.04 as base image and build my own nodeJS baked image. My Dockerfile content looks like below

FROM ubuntu:14.04

MAINTAINER nmrony

#install packages, nodejs and npm
RUN apt-get -y update && \
    apt-get -y install build-essential && \
    curl -sL https://deb.nodesource.com/setup | bash - && \
    apt-get install -y nodejs

#Copy the sources to Container
COPY ./src /src
CMD ["cd /src"]
CMD ["npm install"]

CMD ["nodejs", "/src/server.js"]

I run container using following command

  • Docker run/star/exec?
  • how to setup continuos deployment from docker-hub to AWS ECS?
  • how to import large file in a local cartodb running in a docker container
  • What is the working directory of a Docker Golang application?
  • Running docker Ubuntu image on Debian enironment
  • How to restrict Docker containers to run on specific CPU cores or group of CPU cores
  • docker run -p 8080:8080 -d --name nodejs_expreriments nmrony/exp-nodejs
    

    It runs fine. But when I try browse http:localhost:8080 it does not run.
    When I run docker logs nodejs_expreriments, I got the following error

    Error: Cannot find module 'express'
        at Function.Module._resolveFilename (module.js:338:15)
        at Function.Module._load (module.js:280:25)
        at Module.require (module.js:364:17)
        at require (module.js:380:17)
        at Object.<anonymous> (/src/server.js:1:77)
        at Module._compile (module.js:456:26)
        at Object.Module._extensions..js (module.js:474:10)
        at Module.load (module.js:356:32)
        at Function.Module._load (module.js:312:12)
        at Function.Module.runMain (module.js:497:10)
    

    I run another container with interactive shell and found that npm is not installed. Can someone help me why NPM is not installed on container? Am I doing something wrong?

  • Docker fails in Visual Studio 2017, how do i get docker to run in VS2017
  • Issues with Running Flask and SQLAlchemy app through Docker
  • Building a generic Camel/Docker image and apply different Camel routes when container starts
  • Gitlab CI fails during npm install
  • Single machine Swarm in Docker 1.12
  • Docker container with entrypoint variable expansion and CMD parameters
  • 2 Solutions collect form web for “Why NPM is not available in Docker Conainter”

    Your fundamental problem is that you can only have exactly one CMD in a Docker file. Each RUN/COPY command builds up a layer during docker build, so you can have as many of those as you want. However, exactly one CMD gets executed during a docker run. Since you have three CMD statements, only one of them actually gets executed (presumably, the last one).

    (IMO, if the Dockerfile team would have chosen the word BUILD instead of RUN and RUN instead of CMD, so that docker build does BUILD statements and docker run does RUN statements, this might have been less confusing to new users. Oh, well.)

    You either want to convert your first two CMDs to RUNs (if you expect them to happen during the docker build and be baked into the image) or perhaps put all three CMDs in a script that you run. Here’s a few solutions:

    (1) The simplest change is probably to use WORKDIR instead of cd and make your npm install a RUN command. If you want to be able to npm install during building so that your server starts up quickly when you run, you’ll want to do:

    #Copy the sources to Container
    COPY ./src /src
    WORKDIR /src
    RUN npm install
    CMD nodejs server.js
    

    (2) If you’re doing active development, you may want to consider something like:

    #Copy the sources to Container
    WORKDIR /src
    COPY ./src/package.json /src/package.json
    RUN npm install
    COPY /src /src
    CMD nodejs server.js
    

    So that you only have to do the npm install if your package.json changes. Otherwise, every time anything in your image changes, you rebuild everything.

    (3) Another option that’s useful if you’re changing your package file often and don’t want to be bothered with both building and running all the time is to keep your source outside of the image on a volume, so that you can run without rebuilding:

    ...
    WORKDIR /src
    VOLUME /src
    CMD build_and_serve.sh
    

    Where the contents of build_and_serve.sh are:

    #!/bin/bash
    npm install && nodejs server.js
    

    And you run it like:

    docker run -v /path/to/your/src:/src -p 8080:8080 -d --name nodejs_expreriments nmrony/exp-nodejs
    

    Of course, that last option doesn’t give you a portable docker image that you can give someone with your server, since your code is outside the image, on a volume.

    Lots of options!

    Your CMD syntax is wrong. You can use the array syntax or the shell style, but you are mixing them up. For the shell style, just do:

    WORKDIR /src
    CMD npm install
    
    Docker will be the best open platform for developers and sysadmins to build, ship, and run distributed applications.