skip to Main Content

I have a React app that I’m trying to Dockerize. Here is my Dockerfile and docker-compose:

FROM node:16.13.1
WORKDIR /app

ENV PATH /app/node_modules/.bin:$PATH

COPY package.json .
COPY package-lock.json .

RUN mkdir -p node_modules/node-sass/vendor/linux-x64-93
RUN curl -L https://github.com/sass/node-sass/releases/download/v7.0.1/linux-x64-93_binding.node -o node_modules/node-sass/vendor/linux-x64-93/binding.node

RUN npm install -g [email protected]
RUN npm install [email protected] -g
RUN npm rebuild node-sass

COPY . .

EXPOSE 3000

CMD ["npm", "start"]
version: "3.8"
services:
  web-cnss:
    build: './editor'
    ports: [ "3000:3000" ]
    container_name: WEB-CNSS
    volumes:
      - '/app/node_modules'

Somehow I need to specify the npm version and also install react-scripts, otherwise it gives an error in another computer.
Besides this, in my computer everything works well, however, my objective is that anyone can clone my project and build it by just simply running "docker-compose up".

I tested it on my colleague’s computer, and this was the error:

Error: Cannot find module 'react'
WEB-CNSS     | Require stack:
WEB-CNSS     | - /usr/local/lib/node_modules/react-scripts/scripts/start.js
WEB-CNSS     |     at Function.Module._resolveFilename (node:internal/modules/cjs/loader:933:15)
WEB-CNSS     |     at Function.resolve (node:internal/modules/cjs/helpers:108:19)
WEB-CNSS     |     at Object.<anonymous> (/usr/local/lib/node_modules/react-scripts/scripts/start.js:43:31)
WEB-CNSS     |     at Module._compile (node:internal/modules/cjs/loader:1101:14)
WEB-CNSS     |     at Object.Module._extensions..js (node:internal/modules/cjs/loader:1153:10)
WEB-CNSS     |     at Module.load (node:internal/modules/cjs/loader:981:32)
WEB-CNSS     |     at Function.Module._load (node:internal/modules/cjs/loader:822:12)
WEB-CNSS     |     at Function.executeUserEntryPoint [as runMain] (node:internal/modules/run_main:81:12)
WEB-CNSS     |     at node:internal/main/run_main_module:17:47 {
WEB-CNSS     |   code: 'MODULE_NOT_FOUND',
WEB-CNSS     |   requireStack: [ '/usr/local/lib/node_modules/react-scripts/scripts/start.js' ]
WEB-CNSS     | }

Maybe it is my package.json that has some errors, so here it is as well:

{
   "name": "editor",
   "version": "0.1.0",
   "private": true,
   "dependencies": {
      "@babel/runtime": "^7.18.3",
      "@convergence/convergence": "^1.0.0-rc.12",
      "@testing-library/jest-dom": "^5.16.4",
      "@testing-library/react": "^12.1.4",
      "@testing-library/user-event": "^13.5.0",
      "ace-builds": "^1.4.14",
      "bootstrap": "^5.1.3",
      "dropzone": "^6.0.0-beta.2",
      "easymde": "^2.16.0",
      "node-sass": "^7.0.1",
      "react": "^18.0.0",
      "react-ace": "^9.5.0",
      "react-bootstrap": "^2.2.3",
      "react-dom": "^18.0.0",
      "react-drag-drop-files": "^2.3.7",
      "react-dropzone": "^14.2.2",
      "react-pro-sidebar": "^0.7.1",
      "react-scripts": "5.0.0",
      "react-simplemde-editor": "^5.0.2",
      "react-sticky-box": "^1.0.2",
      "simplemde": "^1.11.2",
      "web-vitals": "^2.1.4"
   },
   "scripts": {
      "predeploy": "npm run build",
      "deploy": "gh-pages -d build",
      "start": "react-scripts start",
      "build": "react-scripts build",
      "test": "react-scripts test",
      "eject": "react-scripts eject"
   },
   "eslintConfig": {
      "extends": [
         "react-app",
         "react-app/jest"
      ]
   },
   "browserslist": {
      "production": [
         ">0.2%",
         "not dead",
         "not op_mini all"
      ],
      "development": [
         "last 1 chrome version",
         "last 1 firefox version",
         "last 1 safari version"
      ]
   },
   "devDependencies": {
      "@convergencelabs/ace-collab-ext": "^0.6.0",
      "gh-pages": "^4.0.0"
   }
}

I also tested the answers on another similar questions posted here on StackOverflow, but they didn’t work.

3

Answers


  1. can you use this pattern to check that you get this error or not again

    FROM node:alpine
    WORKDIR /app
    ENV PATH /app/node_modules/.bin:$PATH
    COPY package.json ./
    COPY package-lock.json ./
    RUN npm install --silent
    RUN npm install [email protected] -g --silent
    RUN npm rebuild node-sass
    
    COPY . ./
    
    Expose 3000
    CMD ["npm", "start"]
    
    Login or Signup to reply.
  2. please remove the command line in dockerfile as follows:

    ...
    
    # RUN npm install [email protected]  -g --silent
    ...
    

    hope this help you.

    Login or Signup to reply.
  3. While your Dockerfile COPYs in the package.json and package-lock.json files, you never actually RUN npm install or a similar command. A Dockerfile often uses npm ci for better reproducibility. Put this right after you COPY in the package metadata.

    COPY package.json package-lock.json ./
    RUN npm ci
    

    Why does it work on your system? Two ideas come to mind, and both point at things to verify in your setup.

    You should make sure that you have a .dockerignore file that excludes the host’s library tree, at least contains the line

    node_modules
    

    If you don’t have this, then the later COPY ./ ./ line will copy the host’s node_modules directory over what npm ci installs. In your original form without the npm ci, it’s probable this was the only thing providing a node_modules directory, but it depended on having run npm commands on the host first.

    The second possibility is the anonymous volume for the node_modules directory. In your docker-compose.yml file you should delete the modules: block

    version: "3.8"
    services:
      web-cnss:
        build: './editor'
        ports: [ "3000:3000" ]
        # container_name: WEB-CNSS  # unnecessary
        # volumes:                  # unnecessary and potentially problematic
        #   - '/app/node_modules'
    

    The anonymous volume sticks around even if a container is deleted and recreated, and its content hides the content in the image. If you ever used a debugging command like docker-compose exec web-cnss npm install, the results of that would stick around in the anonymous volume, but that wouldn’t be part of your image and you wouldn’t see its effects on a clean install.

    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search