Reputation: 1787
I was wondering if anyone had any experience using create-react-app with docker. I was able to get it set up with a Dockerfile like:
from node
RUN mkdir /src
WORKDIR /src
ADD package.json /src/package.json
RUN npm install
EXPOSE 3000
CMD [ "npm", "start" ]
And then used a docker-compose file like:
app:
volumes:
- "./app:/src"
ports:
- "3000:3000"
- "35729:35729"
build: ./app
This allowed me to start up the container and view the app. However livereload didn't work when saving files in the mounted volume and webpack created several .json.gzip files in the src directory.
Any suggestions for getting this working correctly?
Upvotes: 16
Views: 29588
Reputation: 204
Here is a simple (pure docker) solution without local installation of runtime (e.g. node):
cd /tmp
docker run -it --rm -v "$PWD":/app -w /app node yarn create react-app my-app
sudo chown -R $USER:root my-app/
cd my-app
nano docker-compose.yml # see docker-compose.yml below
docker compose up -d
docker-compose.yml:
services:
node:
image: node:16-alpine
environment:
- CHOKIDAR_USEPOLLING=true
- FAST_REFRESH=true
working_dir: /app
ports:
- '3000:3000'
command: "yarn start"
volumes:
- './:/app'
open localhost:3000 in your browser. Hot reload should work out of the box.
Upvotes: 0
Reputation: 53
Not exactly a direct improvement of the author's code, but I was able to get a development environment working with very little code - and no direct dependency to node on my machine - like this:
services:
node:
image: node:16
user: "node"
command: "npm start"
working_dir: /app
volumes:
- ./:/app
ports:
- 3000:3000
This way, you avoid creating docker images from a Dockerfile
.
Usage is generally like this:
docker compose run node npm install
docker compose up
docker compose run node npm install [package name]
compose run
: docker compose rm
Upvotes: 2
Reputation: 876
Running with CRA 4.0 and many dependencies
.dockerignore
.git
.gitignore
node_modules
build
Dockerfile.dev
FROM node:alpine
WORKDIR /app
COPY package.json /app
RUN yarn install
COPY . .
CMD ["yarn", "start"]
docker-compose.dev.yml
version: "3.8"
services:
print:
stdin_open: true
build:
context: .
dockerfile: Dockerfile.dev
ports:
- "3000:3000"
volumes:
- ".:/app"
- "/app/node_modules"
Dockerfile.prod
FROM node:alpine as build
WORKDIR /app
COPY package.json /app
RUN yarn install
COPY . /app
RUN yarn run build
FROM nginx:stable-alpine
COPY ./nginx/nginx.conf /etc/nginx/conf.d/default.conf
COPY --from=build /app/build /usr/share/nginx/html
docker-compose.prod.yml
version: "3.8"
services:
print:
stdin_open: true
build:
context: .
dockerfile: Dockerfile.prod
ports:
- "80:80"
nginx.conf
server {
listen 80;
server_name frontend;
location / {
root /usr/share/nginx/html;
index index.html;
try_files $uri /index.html;
}
}
To run
docker-compose.exe -f .\docker-compose.yml up --build
or
docker-compose.exe -f .\docker-compose.dev.yml up --build
Upvotes: 1
Reputation: 454
While using docker in development with create-react-app, i discovered that it is possible to override the webpackDevServer configuration by adding CHOKIDAR_USEPOLLING=1
to your .env file. This will make the file watching work again. It even refreshes the browser page on the host! The only thing that i discovered is that it doesn't open up a webpage automatically.
I can also advise to add tty: true
to your service to have your original console output back into your terminal. To remove the container name prefixes in the logs, you can run something like this after running docker-compose up -d
:
docker-compose logs -f --tail=100 client | cut -f2 -d \"|\""
Upvotes: 1
Reputation: 12450
here is good gide for this https://mherman.org/blog/dockerizing-a-react-app/
for development
# base image
FROM node:9.6.1
# set working directory
RUN mkdir /usr/src/app
WORKDIR /usr/src/app
# add `/usr/src/app/node_modules/.bin` to $PATH
ENV PATH /usr/src/app/node_modules/.bin:$PATH
# install and cache app dependencies
COPY package.json /usr/src/app/package.json
RUN npm install --silent
RUN npm install [email protected] -g --silent
# start app
CMD ["npm", "start"]
for production
# build environment
FROM node:9.6.1 as builder
RUN mkdir /usr/src/app
WORKDIR /usr/src/app
ENV PATH /usr/src/app/node_modules/.bin:$PATH
COPY package.json /usr/src/app/package.json
RUN npm install --silent
RUN npm install [email protected] -g --silent
COPY . /usr/src/app
RUN npm run build
# production environment
FROM nginx:1.13.9-alpine
COPY --from=builder /usr/src/app/build /usr/share/nginx/html
EXPOSE 80
CMD ["nginx", "-g", "daemon off;"]
Upvotes: 4
Reputation: 1265
I recently made a small project called hello-docker-react who just does what the op is looking for.
It's made with docker-compose, create-react-app, yarn, a node image, and a small entrypoint script.
Live reload work flawlessly and I haven't found any problems yet.
https://github.com/lopezator/hello-docker-react
Upvotes: 6
Reputation: 22341
Yeah, as aholbreich mentioned, I'd use npm install
/ npm start
locally on my machine for development, just because it's so easy. It's probably possible with docker-compose
, mounting volumes etc. too, but I think it could be a bit fiddly to set up.
For deployment you can then very easily use a Dockerfile. Here's an example Dockerfile I'm using:
FROM node:6.9
# Create app directory
RUN mkdir -p /src/app
WORKDIR /src/app
# to make npm test run only once non-interactively
ENV CI=true
# Install app dependencies
COPY package.json /src/app/
RUN npm install && \
npm install -g pushstate-server
# Bundle app source
COPY . /src/app
# Build and optimize react app
RUN npm run build
EXPOSE 9000
# defined in package.json
CMD [ "npm", "run", "start:prod" ]
You need to add the start:prod
option to your package.json:
"scripts": {
"start": "react-scripts start",
"start:prod": "pushstate-server build",
"build": "react-scripts build",
"test": "react-scripts test --env=jsdom",
"eject": "react-scripts eject"
},
You can run the tests on your CI service with:
docker run <image> npm test
There's nothing stopping you from running this docker container locally as well to make sure things work as expected.
Upvotes: 10