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
can you use this pattern to check that you get this error or not again
please remove the command line in dockerfile as follows:
hope this help you.
While your Dockerfile
COPY
s in thepackage.json
andpackage-lock.json
files, you never actuallyRUN npm install
or a similar command. A Dockerfile often usesnpm ci
for better reproducibility. Put this right after youCOPY
in the package metadata.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 lineIf you don’t have this, then the later
COPY ./ ./
line will copy the host’snode_modules
directory over whatnpm ci
installs. In your original form without thenpm ci
, it’s probable this was the only thing providing anode_modules
directory, but it depended on having runnpm
commands on the host first.The second possibility is the anonymous volume for the
node_modules
directory. In yourdocker-compose.yml
file you should delete themodules:
blockThe 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.