Most of the times I use Docker with volumes. But Now I am trying bind mounts for the first time and they are not working as I expected. I'm probably missing something or maybe not understanding completely they way they work.
Let's take this example. I have a React app created with create-react-app and it will run with a Rails backend based on a MySQL database.
My directory structure is:
App
├── docker
│ ├── api
│ │ └── Dockerfile
│ └── fe
│ ├── Dockerfile
│ ├── package.json
│ ├── package-lock.json
│ ├── public
│ ├── README.md
│ └── src
├── docker-compose.yml
I started by creating the docker-compose.yml file like this:
version: "3.7"
services:
web:
build: ./docker/fe/.
ports: ["80:3000"]
volumes:
- type: bind
source: "./docker/fe"
target: "/app"
As you may see, I am mapping the directory ./docker/fe, where the React frontend is, to /app.
Inside ./docker/fe is the Dockerfile:
FROM node:8
WORKDIR /app
RUN npm install
CMD ["npm","start"]
I was expecting this to work, because my app files are all inside /app, mapped to ./docker/fe. At least I thought they would be! But when I run the docker-compose up --build command at the command line I get a build error, because it says there is no package.json file inside the /app directory.
On the other hand, when I use this other version of Dockerfile
FROM node:8
WORKDIR /app
ADD package.json .
ADD package-lock.json .
RUN npm install
ADD . .
CMD ["npm","start"]
this problem won't happen. It will find the package.json file and build the app correctly. But it won't run!
The fact is, it will say it can't find the React scripts. And it is no surprise, since when it is finished there is no node_modules directory inside ./docker/fe as it would be expected after running npm install.
I am confused.
Am I missing something about the bind mounts?
Why do I need to ADD package.json to the WORKDIR if this directory is associated with the host directory where this file already is?
Why I don't have a node_modules directory inside ./docker/fe after npm install?
Docker volumes are only mounted when image is run, not during build phase.
Add these back in to your Dockerfile:
ADD package.json .
ADD package-lock.json .
And/or:
ADD . .
Related
I have a monorepo setup like:
└── monorepo/
├── package.json
├── apps/
│ └── website/
│ └── package.json
└── packages/
└── elements/
└── package.json
From the monorepo root I'd like to be able to have a command that runs a build watch on the elements package and then concurrently serves up website.
I see that Nx has a run-many command, but that seems more useful if you trying to run a similar command across multiple packages, for example running test on multiple packages at the same time. My situation is different, I want to run build in one and serve in the other.
I'm guessing I'm missing something with the configuration files.
I'm trying to deploy my react app, by serving it using nginx.
The app works perfectly if I serve it using react-scripts start. When I try to serve it with nginx, the main app works fine but the static pages in public folder they don't work.
ex: if I try to navigate to /cgu it redirect me to localhost/cgu.
This is my work directory for (unnecessary files and folders are not mentioned for brevity).
├── Dockerfile
├── docker-compose.yml
├── nginx.conf
├── package-lock.json
├── package.json
├── public
│ ├── assets
│ ├── browserconfig.xml
│ ├── cgu
│ ├── index.html
└── src
├── App.css
├── App.js
├── index.css
└── index.js
This my docker file's content:
FROM node:16-alpine as builder
WORKDIR /app
COPY . .
RUN npm i --legacy-peer-deps
RUN npm run build
FROM nginx:1.21.0-alpine as production
ENV NODE_ENV production
COPY --from=builder /app/build /usr/share/nginx/html
COPY default.conf /etc/nginx/conf.d/default.conf
EXPOSE 80
CMD ["nginx", "-g", "daemon off;"]
I have multiple React repos cloned from gitlab within my work folder. I want to implement a work-wide eslint configuration, whereby every project has the same eslint rules. As such, I want to first npm install eslint#7 --save-devevery repo (this repo comes with React best-practice eslint recommendations).
Is there way to npm install for every repo once from one folder above? I don't want to install it globally.
I will then use a bash script to add a eslintrc file to each repo at root level.
example of repos:
work dir
├── react-app-one
├── react-app-two
├── app-three
├── app-four
├── app-five
Look at npm workspaces since this does exactly what you ask for
I'm getting back this error when I try NPM start on windows after creating a react file.
$ npm start
npm ERR! code ENOENT
npm ERR! syscall open
npm ERR! path C:\Users\Ronan\desktop\package.json
npm ERR! errno -4058
npm ERR! enoent ENOENT: no such file or directory, open 'C:\Users\Ronan\desktop\package.json'
Edit: Heres a pic of my file tree if that helps.
To get a react project running, you would have to use a tool called the Node Package Execute "npx" to kickstart a create-react-app project, see illustration below:
npx create-react-app your-app-name
Doing this will generate a small react project with all the directories/files you need to start building your react app,
The directory you should get will look like the below:
your-app-name
├── README.md
├── node_modules
├── package.json
├── .gitignore
├── public
│ ├── favicon.ico
│ ├── index.html
│ └── manifest.json
└── src
├── App.css
├── App.js
├── App.test.js
├── index.css
├── index.js
├── logo.svg
└── serviceWorker.js
└── setupTests.js
running npm start inside this directory should kickstart a localhost:3000 server where you can see a preview of your project in your browser.
I have created my first react-js app, just saying 'Hello world'. After I change the 'Hello world' to another text, nothing changes when I refresh the browser, even if I empty the cache. The changes take place only when I close the local server and reopen it with npm start. Could anyone help me?
If you want to create new react app from-scratch. You can use :
> npx create-react-app my-app
> cd my-app
> npm start
After that, you will have the initial configured react project structure :
my-app
├── README.md
├── node_modules
├── package.json
├── .gitignore
├── public
│ └── favicon.ico
│ └── index.html
│ └── manifest.json
└── src
└── App.css
└── App.js
└── App.test.js
└── index.css
└── index.js
└── logo.svg
└── registerServiceWorker.js
See react app seed in Github : https://github.com/facebook/create-react-app.
Sam's answer is probably the best way to do it but if you want do refresh it without adding all the bells and whistles of create-react-app you can go for browsersync.
https://browsersync.io/
It watches over your CSS, HTML, JS. I usually use create-react-app but in some cases browsersync does the trick as well.