How to access create-react-app run in a docker container? - reactjs

I followed the steps under https://mherman.org/blog/dockerizing-a-react-app/
My setup:
Windows 10 Home
docker commands are run in the Docker Quickstart Terminal https://docs.docker.com/toolbox/toolbox_install_windows/
How to reproduce: Follow the steps from the first link:
install create-react-app globally:
npm install -g create-react-app#3.4.1
Generate new app:
$ npm init react-app sample --use-npm
$ cd sample
Create Dockerfile in the root of directory:
# pull official base image
FROM node:13.12.0-alpine
# set working directory
WORKDIR /app
# add `/app/node_modules/.bin` to $PATH
ENV PATH /app/node_modules/.bin:$PATH
# install app dependencies
COPY package.json ./
COPY package-lock.json ./
RUN npm install --silent
RUN npm install react-scripts#3.4.1 -g --silent
# add app
COPY . ./
# start app
CMD ["npm", "start"]
Add .dockerignore:
node_modules
build
.dockerignore
Dockerfile
Dockerfile.prod
Build and tag the dockerimage:
$ docker build -t sample:dev .
Spin up the container:
$ docker run \
-it \
--rm \
-v ${PWD}:/app \
-v /app/node_modules \
-p 3001:3000 \
-e CHOKIDAR_USEPOLLING=true \
sample:dev
This is what I see in the Docker Quickstart Terminal:
And this is my project structure:
However, when I go to localhost:3001 as described in the post, I see
Any idea where I'm missing something?

When you run the container, specify the port like this: 3000:80 (use :80)
$ docker run -it --rm -p 3000:80 sample:prod
You can then navigate to http://localhost:3000/ to see the CRA app.

Related

This page isn’t working localhost didn’t send any data. ERR_EMPTY_RESPONSE

I have a problem. when try to run my dockerFile in React app.
When I try to run my DockerFile
FROM node:16
ENV REACT_APP_baseUrl = https://localhost:44377/api
ENV REACT_APP_baseUrlFile = https://localhost:3000/files
ENV REACT_APP_baseUrlFileMetadata = https://localhost:3000/files/metaData
ENV REACT_APP_FILESTORAGE_KEY = ./fileStorage.key
ENV REACT_APP_FILESTORAGE_PEM = ./fileStorage.pem
ENV REACT_APP_ROOT_CA = ./rootCA.pem
ENV REACT_APP_baseUrlReact = http://localhost:8080
WORKDIR /app-ui
COPY package.json ./
COPY yarn.lock ./
COPY package-lock.json ./
COPY ./ ./
RUN yarn install
EXPOSE 8080
CMD ["yarn", "start"]
Then I run:
docker build -f Dockerfile -t client .
docker run -it -p 8080:8080 client
And get
But I do not understand the problem.
Please help
I can provide container status
You did not specify the that CRA should use for the development server. You can do so with the -e as such:
docker run -it -p 8080:8080 -e "PORT=8080" client

Dockerize a React-Django project where the frontend is served from Django

I am serving a react app from within Django, and I trying to deploy it using docker-compose up -d --build.
My project directory is as follows:
root
├──project (django)
| ├──frontend/ # react project is here
| ├──project/
| ├──static/
| ├──Dockerfile //Dockerfile for backend image
| ├──entrypoint.sh
| ├──manage.py
| ├──requirements.txt
└──docker-compose.yaml
Here is my current deploy script:
# pull the official base image
FROM python:3.8.12-bullseye
# set work directory
WORKDIR /usr/src/app
# set environment variables
ENV PYTHONDONTWRITEBYTECODE 1
ENV PYTHONUNBUFFERED 1
# install dependencies
RUN apt-get update
COPY /requirements.txt /usr/src/app
RUN pip install -r requirements.txt
# set work directory
WORKDIR ~/usr/src/app
COPY package.json ./
COPY package-lock.json ./
RUN npm install --silent
RUN npm install react-scripts#3.4.1 -g --silent
RUN npm run dev
# set work directory
WORKDIR /usr/src/app
# copy project
COPY . /usr/src/app/
# run entrypoint.sh
ENTRYPOINT ["/usr/src/app/entrypoint.sh"]
The error I get
> => ERROR [12/18] COPY package.json ./
> 0.0s => ERROR [13/18] COPY package-lock.json ./ 0.0s ------
> > [12/18] COPY package.json ./:
> ------
> ------
> > [13/18] COPY package-lock.json ./:
> ------ failed to compute cache key: "/package-lock.json" not found: not found
I edited your Dockerfile, try if this works:
# pull the official base image
FROM python:3.8.12-bullseye
RUN apt-get update
COPY . ./usr/src/app
WORKDIR /usr/src/app
# set environment variables
ENV PYTHONDONTWRITEBYTECODE 1
ENV PYTHONUNBUFFERED 1
# install python dependencies
RUN pip install -r requirements.txt
WORKDIR /usr/src/app/frontend
RUN npm install --silent
RUN npm install react-scripts#3.4.1 -g --silent
RUN npm run dev
# run entrypoint.sh
ENTRYPOINT ["/usr/src/app/entrypoint.sh"]
The issue is that package.json and package-lock.json are not present in the directory where you run docker build, but (probably) in your frontend subdirectory.
Changing those two lines to:
COPY frontend/package.json ./
COPY frontend/package-lock.json ./
should work. But better yet, since you're copying everything anyway, you can move that to the top:
# pull the official base image
FROM python:3.8.12-bullseye
# set work directory
WORKDIR /usr/src/app
# copy project
COPY . .
# set environment variables
ENV PYTHONDONTWRITEBYTECODE 1
ENV PYTHONUNBUFFERED 1
# install dependencies
RUN apt-get update
RUN apt-get update \
&& apt-get install -y curl \
&& curl --silent --location https://deb.nodesource.com/setup_12.x | bash - \
&& apt-get install -y nodejs \
&& npm install --silent\
&& npm install react-scripts#3.4.1 -g --silent
RUN pip install -r requirements.txt
# set work directory
WORKDIR /usr/src/app/frontend
RUN npm install --silent
RUN npm install react-scripts#3.4.1 -g --silent
RUN npm run dev
# set work directory
WORKDIR /usr/src/app
# run entrypoint.sh
ENTRYPOINT ["/usr/src/app/entrypoint.sh"]
I'm not sure what your needs are, but for a production environment I would suggest separating the frontend and Django application into different containers. Backend applications have very different scaling and hardware needs than frontend applications. You can still package it into one application using Docker-compose for example.

npm run tests in docker with travis CI

I am deploying a react app to Heroku via TravisCI. The fact that I'm using Heroku doesn't really affect what I'm about to ask, I'm pretty sure, it's just there for context. Travis successfully deploys the app until I add a testing step (the script section) in .travis.yml:
language: generic
sudo: required
services:
- docker
before_install:
- docker build -t myapp:prod -f Dockerfile.prod .
script:
- docker run -e CI=true myapp:prod npm run test
after_success:
- docker build -t myapp:prod -f Dockerfile.prod .
- echo "$DOCKER_PASSWORD" | docker login -u "$DOCKER_ID" --password-stdin
- docker push myapp:prod
deploy:
provider: heroku
app: myapp
skip_cleanup: true
api_key:
secure: <my_key>
However, my Dockerfile.prod is a multi-stage node + nginx where the nginx stage doesn't keep any node or npm stuff:
# build environment
FROM node:13.12.0-alpine as builder
# set working directory
WORKDIR /app
# add `/app/node_modules/.bin` to $PATH
ENV PATH /app/node_modules/.bin:$PATH
# install app dependencies
COPY package.json ./
COPY package-lock.json ./
# some CI stuff I guess
RUN npm ci
RUN npm install react-scripts#3.4.1 -g --silent
COPY . ./
RUN npm run build
# production environment
FROM nginx:stable-alpine
COPY nginx.conf /etc/nginx/conf.d/default.conf
# If using React Router
COPY --from=builder /app/build /usr/share/nginx/html
# For Heroku
CMD sed -i -e 's/$PORT/'"$PORT"'/g' /etc/nginx/conf.d/default.conf && nginx -g 'daemon off;'
Therefore, it is my understanding that .travis.yml tries to run that npm run test command inside my nginx container and can't execute npm commands (no node installed, right?). So guided by SO answers such as this one I started adding commands into that nginx stage such as
COPY package.json ./
COPY package-lock.json ./
RUN apk add --update npm
but I realized I might be approaching this the wrong way. Should I perhaps be adding npm through Travis? That is, should I include in .travis.yml in the scripts section something like docker run -e CI=true myapp:prod apk add --update npm and whatever else is necessary? This would result in a smaller nginx image no? However, would I run into problems with package.json from the node stage in Dockerfile.prod or anything like that?
In summary, to use TravisCI to test a dockerized react app served with nginx, at what point should I install npm into my image? Does it happen as part of script in .travis.yml or does it happen in Dockerfile.prod? If it is recommened to npm run tests inside Dockerfile.prod, would I do that in the first stage (node) or the second (nginx)?
Thanks
EDIT: Not sure if this can be considered solved, but a user on Reddit recommended to simply RUN npm run test right before the RUN npm run build.

Running a react app in docker : react app in docker fails to run

I am trying to run a react app in a docker image however it exits without an error message
DokerFile
# pull official base image
FROM node:13.12.0-alpine
# set working directory
WORKDIR /app
# add `/app/node_modules/.bin` to $PATH
ENV PATH /app/node_modules/.bin:$PATH
# install app dependencies
COPY package.json ./
COPY package-lock.json ./
RUN npm install
# add app
COPY . ./
# start app
CMD npm start --port 3000
then I proceeded to build
docker build -t react-app:latest .
then I run
docker run -p 7000:3000 react-app:latest
gives the following out put
then exits out
this is what I see on the browser
Your docker closes because the tty is not enabled.
In order to work, you have to run the docker with
docker run -t -p 7000:3000 react-app:latest
For more info: https://github.com/facebook/create-react-app/issues/8688
But this should be only for testing/development. In production you should build your react app and then serve it with serve or with nginx

Docker : Unable to find local grunt

I try to dockerise an old angularJS app but I hang at a problem. I have the impression that when docker dials up my volume it overwrites all that has been done previously.
My image is built successfully but when I run it I have this error:Fatal error: Unable to find local grunt.
My goal is to be able to build my app while keeping the hot reload.
Dockerfile :
FROM mhart/alpine-node:6 as builder
# Confirm versions
RUN node -v
RUN npm -v
# Add
COPY package.json /usr/src/app/package.json
COPY bower.json /usr/src/app/bower.json
COPY Gruntfile.js /usr/src/app/Gruntfile.js
COPY .bowerrc /usr/src/app/.bowerrc
# Define app as root dir
WORKDIR /usr/src/app
# add app
#COPY . /usr/src/app
# Install sass & compass
RUN apk update && \
apk upgrade
RUN apk add --update \
ruby \
ruby-irb \
ruby-dev \
ruby-rdoc \
libffi-dev \
build-base
RUN gem install \
sass \
compass
# Install Perl
RUN apk add perl
# Install Git (rquired for angular dep)
RUN apk add git
# Install Yarn
RUN npm install -g yarn
RUN yarn -v
# Install dependencies
RUN npm install bower -g\
&& npm install -g grunt-cli \
&& yarn add grunt-contrib-imagemin \
&& yarn
# Build
RUN bower install --allow-root
EXPOSE 9000 35729
CMD [ "grunt", "--force" ,"server" ]
**docker-compose : **
version: '3.7'
services:
app-dev:
container_name: app-dev
build:
context: .
dockerfile: Dockerfile-dev
volumes:
- .:/usr/src/app/
ports:
- '9000:9000'
- '35729:35729'
restart: always
Doesn't look like you're running npm install on the docker image, which means that none of your packages from your package.json are going to present.
You should, in general, exclude node_modules from the docker build context with a .dockerignore, as you're going to want to rebuild your dependencies inside the container. A dependent module can, for instance, need to compile a native module for something. For instance, node-sass has a compiled component.

Resources