0

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 npm@9.1.2
RUN npm install react-scripts@5.0.0 -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.

4b0
  • 21,981
  • 30
  • 95
  • 142
Im Kumin
  • 3
  • 3
  • I think that the problem lays with the node version installed. Have you checked that? – Alen.Toma Nov 30 '22 at 16:47
  • are you sure that copy package-lock into dockerfile is right?. I think you just should copy package.json and then npm install to build that file then. – ali Falahati Nov 30 '22 at 16:50
  • @Alen.Toma The version I use in the dockerfile is the same that I have installed on my local computer. My colleague doesn't even have node installed. But, since this is a docker container, the FROM node:16.13.1 should install the node on the container, no? – Im Kumin Nov 30 '22 at 16:51
  • I also tried without package-lock, but the error persisted. @aliFalahati – Im Kumin Nov 30 '22 at 16:53

3 Answers3

0

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 react-scripts@5.0.0 -g --silent
RUN npm rebuild node-sass

COPY . ./

Expose 3000
CMD ["npm", "start"]
ali Falahati
  • 599
  • 7
  • 18
  • If i do not specify the version 9.1.2 it gives an error. That is why i specified it on my dockerfile: ` #0 3.280 npm notice New major version of npm available! 8.19.3 -> 9.1.2 #0 3.280 npm notice Changelog: https://github.com/npm/cli/releases/tag/v9.1.2 #0 3.281 npm notice Run npm install -g npm@9.1.2 to update! ` – Im Kumin Nov 30 '22 at 16:59
  • npm install -g npm is for updating npm. and you dont need it at all. when you use an image with its version (here node:16.13.1) then you have the latest version of component inside it. and its not necessary here. you should remove this command in my opinion. – ali Falahati Nov 30 '22 at 17:01
  • I agree, but why does it gives an error then? It forces me to run npm install -g npm@9.1.2 ... – Im Kumin Nov 30 '22 at 17:05
0

please remove the command line in dockerfile as follows:

...

# RUN npm install react-scripts@5.0.0  -g --silent
...

hope this help you.

hotbrainy
  • 331
  • 1
  • 10
  • I'm already doing that on my dockerfile. – Im Kumin Nov 30 '22 at 17:07
  • is it working now? – hotbrainy Nov 30 '22 at 17:22
  • Sorry but no, it gives this error: ` #0 2.959 npm ERR! code ERESOLVE #0 2.962 npm ERR! ERESOLVE unable to resolve dependency tree #0 2.962 npm ERR! #0 2.962 npm ERR! While resolving: editor@0.1.0 #0 2.963 npm ERR! Found: react@18.2.0 #0 2.963 npm ERR! node_modules/react #0 2.963 npm ERR! react@"^18.0.0" from the root project ` – Im Kumin Nov 30 '22 at 17:31
  • Can you show me entire error messages? – hotbrainy Nov 30 '22 at 17:36
  • If I remove completely the line you mentioned it simply says: "sh: 1: react-scripts: not found" – Im Kumin Nov 30 '22 at 17:43
0

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.

David Maze
  • 130,717
  • 29
  • 175
  • 215