Home > Net >  docker-compose cant run react without node_modules already existing
docker-compose cant run react without node_modules already existing

Time:04-14

Im using docker/docker-compose to get my react (ts) app up and running. The script im currently using works perfectly, on 1 condition. That I've already did 'npm install' inside the directory, while not in docker.

I would like to be able to clone my project from github, and just do docker-compose up, and that it works than.

Right now i first have to run 'npm install', and than 'docker-compose up' for it to work sadly.

I tried just using RUN npm install react-scripts -g, and that kinda works. however i than get a error for typescript, and all other packages.

What I want to be happening is. When I clone my repo, and use docker-compose up. That my whole project runs. It also should make a node_modules folder in my react folder that I can see in my IDE. This is so that my IDE knows the code in the package and doesn't yell at me the whole time.

I cant figure out how to get this to work, I'm already struggling on this for hours and can't find online how to fix it. Hope anyone can help me :D

My structure looks something like this:

  • apps
    • frontend
      • Dockerfile
      • composer.json
      • // All the other react files/folders
  • docker-compose.yml

Dockerfile:

FROM node:16.14.2

WORKDIR /usr/src/app

COPY ./package*.json ./

RUN npm install

CMD npm start --host 0.0.0.0 --port 3000 --disableHostCheck true

docker-compose.yml:

version: '3'

services:
    frontend:
        build:
            context: ./apps/frontend
            dockerfile: ./Dockerfile
        volumes:
            - ./apps/frontend:/usr/src/app
        ports:
            - 3000:3000
        environment:
            - CHOKIDAR_USEPOLLING=true
            - API_BASE_URL=host.docker.internal:8080/api
        extra_hosts:
            - "host.docker.internal:host-gateway"

The error im getting is:

frontend_1  | > [email protected] start
frontend_1  | > react-scripts start "0.0.0.0" "3000"
frontend_1  | 
frontend_1  | sh: 1: react-scripts: not found
cyldiscordbot_frontend_1 exited with code 127

package.json (idk if you need it, but here it is):

{
  "name": "spa",
  "version": "0.1.0",
  "private": true,
  "dependencies": {
    "@cylbot/cyldiscordbotlanguage": "^2.0.3",
    "@emotion/core": "^11.0.0",
    "@emotion/react": "^11.7.1",
    "@emotion/styled": "^11.6.0",
    "@mui/icons-material": "^5.3.1",
    "@mui/material": "^5.5.0",
    "@testing-library/user-event": "^13.2.1",
    "@types/node": "^17.0.9",
    "@types/react": "^17.0.38",
    "@types/react-dom": "^17.0.11",
    "axios": "^0.25.0",
    "emotion-theming": "^11.0.0",
    "enzyme": "^3.11.0",
    "react": "^17.0.2",
    "react-dom": "^17.0.2",
    "react-redux": "^7.2.6",
    "react-router-dom": "^6.2.1",
    "react-scripts": "5.0.0",
    "redux": "^4.1.2",
    "redux-saga": "^1.1.3",
    "redux-thunk": "^2.4.1",
    "styled-components": "^5.3.3",
    "typescript": "^4.5.4",
    "web-vitals": "^2.1.0"
  },
  "scripts": {
    "start": "react-scripts start",
    "build": "react-scripts build",
    "test": "jest",
    "test:watch": "jest --watch",
    "test:coverage": "jest --coverage",
    "storybook": "start-storybook -p 6006 -s public",
    "build-storybook": "build-storybook -s public"
  },
  "eslintConfig": {
    "extends": [
      "react-app",
      "react-app/jest"
    ],
    "overrides": [
      {
        "files": [
          "**/*.stories.*"
        ],
        "rules": {
          "import/no-anonymous-default-export": "off"
        }
      }
    ]
  },
  "browserslist": {
    "production": [
      ">0.2%",
      "not dead",
      "not op_mini all"
    ],
    "development": [
      "last 1 chrome version",
      "last 1 firefox version",
      "last 1 safari version"
    ]
  },
  "devDependencies": {
    "@material-ui/core": "^4.12.3",
    "@storybook/addon-actions": "^6.4.19",
    "@storybook/addon-essentials": "^6.4.19",
    "@storybook/addon-interactions": "^6.4.19",
    "@storybook/addon-links": "^6.4.19",
    "@storybook/builder-webpack5": "^6.4.19",
    "@storybook/manager-webpack5": "^6.4.19",
    "@storybook/node-logger": "^6.4.19",
    "@storybook/preset-create-react-app": "^4.0.1",
    "@storybook/react": "^6.4.19",
    "@storybook/testing-library": "^0.0.9",
    "@testing-library/jest-dom": "^5.16.2",
    "@testing-library/react": "^12.1.4",
    "@testing-library/react-hooks": "^7.0.2",
    "@types/jest": "^27.4.1",
    "@types/styled-components": "^5.1.20",
    "jest": "^27.5.1",
    "react-test-renderer": "^17.0.2",
    "ts-jest": "^27.1.3",
    "webpack": "^5.70.0"
  }
}

I can give out a lot of info about this project, so if more info is required just ask! :D

CodePudding user response:

I figured it out. I asked a friend, and he helped me out. I needed to change my Dockerfile to:

FROM node:16.14.2

WORKDIR /usr/src/app

RUN npm install -g react-scripts

RUN chown -Rh node:node /usr/src/app

USER node

EXPOSE 3000

CMD [ "sh", "-c", "npm install && npm run start" ]

CodePudding user response:

Your Dockerfile is missing the application code; it only copies the package.json file in. This gives you an incomplete image that you can't just run. You're missing a line:

COPY ./ ./

I'd put this after the RUN npm install line, to make rebuilding the image faster.

Since your image is incomplete, in your current setup you have to inject the code from the host, and that hides the node_modules directory that the image builds. That's why you also have to run npm install on the host. If you COPY the application code into the image, you don't need the volumes: block.

version: '3.8'
services:
    frontend:
        build: ./apps/frontend  # short form with default dockerfile:
        ports:
            - 3000:3000
        environment:
            - API_BASE_URL=host.docker.internal:8080/api
        extra_hosts:
            - "host.docker.internal:host-gateway"
        # no volumes: or polling environment variable
  • Related