NodeJS in Docker – cannot access node_modules

We have a NodeJS project building with Jenkins inside Docker containers.

The problem is taht after image started – we have an error:

  • Deploy AngularJS app into docker container
  • Copy apidoc files from dokku container to host apache folder
  • Starting Docker as Daemon on Ubuntu
  • How to backup/restore docker image for deployment?
  • Centos and Fedora Docker, I can not start mysql
  • docker-compose scale does not work with haproxy
  • transform_1 | > node ./build/server.js
    transform_1 | 
    transform_1 | module.js:472
    transform_1 |     throw err;
    transform_1 |     ^
    transform_1 | 
    transform_1 | Error: Cannot find module './lib/express'
    transform_1 |     at Function.Module._resolveFilename (module.js:470:15)
    

    During build in Jenkins – I check permissions and they are OK:

    ...
    + ls -l node_modules/express/lib
    total 80
    -rw-r--r-- 1 jenkins 1001 14202 Feb 28 12:18 application.js
    -rw-r--r-- 1 jenkins 1001  1954 Feb 28 12:18 express.js
    drwxr-xr-x 2 jenkins 1001  4096 Feb 28 12:18 middleware
    ...
    

    But from container – there is “Permission denied” error:

    admin@swarm-master-EB25F3D5-0:~$ docker run -ti automation/cms-transform-layer bash
    app@3b86a8e8cc4d:~$ ls -l node_modules/express/
    ls: cannot access node_modules/express/lib: Permission denied
    ls: cannot access node_modules/express/node_modules: Permission denied
    total 124
    -rw-r--r-- 1 app app 99111 Feb 28 12:18 History.md
    -rw-r--r-- 1 app app  1249 Feb 28 12:18 LICENSE
    -rw-r--r-- 1 app app  4541 Feb 28 12:18 Readme.md
    -rw-r--r-- 1 app app   224 Feb 28 12:18 index.js
    d????????? ? ?   ?       ?            ? lib
    d????????? ? ?   ?       ?            ? node_modules
    -rw-r--r-- 1 app app  4939 Feb 28 12:18 package.json
    

    What the hell is "d????????? ? ? ? ? ? node_modules"?

    The Dockerfile is:

    FROM node:7.5.0
    
    RUN useradd --user-group --create-home --shell /bin/false app
    
    ENV HOME=/home/app
    
    USER root
    COPY . $HOME/
    RUN chown -R app:app $HOME/*
    
    USER app
    WORKDIR $HOME
    
    CMD ["npm", "run", "start:production"]
    

    UPD

    Related entries in package.json:

    ...
    "contentful": "^3.8.0",
    "express": "^4.14.0",
    "jsum": "^0.1.1",
    ...
    

    Service definition from docker-compose.yml:

    ...
    transform:
    environment:
      - LOGZ_TOKEN=""
      - LOGZIO_API_KEY=""
      - NPM_TOKEN=""
    image: "company/transform-layer:latest"
    restart: "always"
    ports:
      - "3003:3003"
    ...
    

    This is Jenkins pipeline script:

    ...
    def npmBuildTransform(repoUrl='1', env='2') {
        docker.image('node').inside('-v /var/run/docker.sock:/var/run/docker.sock') {
            git branch: "${BRANCH}", credentialsId: 'github', url: "${repoUrl}"
            stage('Transform build') {
               sh 'apt-get update && apt-get -y install rsync'
               sh 'npm config set //registry.npmjs.org/:_authToken=$NPM_TOKEN'
               sh 'npm install --production=false'
               ...
    

  • Can't push docker image to gcloud
  • Can a docker image use executable from the host?
  • Start and attach a docker container with X11 forwarding
  • Exposing multiple ports from within a ManagedVM
  • How can I use Windows Containers for Software Testing?
  • asp.net web api on docker stops
  • One Solution collect form web for “NodeJS in Docker – cannot access node_modules”

    The solution.

    I moved all Node’s build logic from Jenkin’s scripts to the Dockerfile, as suggested by Patric and some resources.

    So, the final result is – call Docker build from the Jenkins:

            ...
            def appimage = docker.build("projectname/${imgName}:${TAG}", "--build-arg NPM_TOKEN=${NPM_TOKEN} .")
    
                appimage.push()
                appimage.push('latest')
            ...
    

    And then I do NPM build from the Dockerfile:

    FROM node:7.5.0
    
    ARG NPM_TOKEN="${NPM_TOKEN}"
    
    RUN useradd --user-group --create-home --shell /bin/false app
    
    ENV HOME=/home/app
    
    USER app
    COPY package.json $HOME/
    
    WORKDIR $HOME
    RUN pwd && ls -l
    
    RUN npm config set //registry.npmjs.org/:_authToken=${NPM_TOKEN}
    
    RUN npm install --production=false
    COPY . $HOME
    
    USER root
    RUN chown -R app:app $HOME/
    
    USER app
    RUN npm run build:production
    
    CMD ["npm", "run", "start:production"]
    

    It’s kind of “dev” version, few redundant steps/layers like RUN pwd && ls -l, but this works.

    Docker will be the best open platform for developers and sysadmins to build, ship, and run distributed applications.