DEV Community

Cover image for Run a React App in a Docker Container

Run a React App in a Docker Container

Peter Jausovec on March 05, 2019

Here are simple steps that show you how to start with an empty React app (using create-react-app), create a production build of that app and then r...
Collapse
 
jwankhalaf profile image
Jwan Khalaf • Edited

Thanks for the article. I have followed along and all seems to build fine. However when I run the image and navigate to localhost:8080 I get a blank page with the text Error: Failed to fetch.

Any ideas on why this might be happening?

Also, what does the -s do in CMD ["serve", "-p", "80", "-s", "."]

Collapse
 
jwankhalaf profile image
Jwan Khalaf

Ignore the first part of my question. The Error: Failed to fetch is what my ReactJS app does when it can't mak calls to the API. :)

Collapse
 
thorakmedichi profile image
Thorak • Edited

When trying to build I am getting this error

[1/4] Resolving packages...

error An unexpected error occurred: "registry.yarnpkg.com/react: getaddrinfo EAI_AGAIN registry.yarnpkg.com registry.yarnpkg.com:443".

Collapse
 
peterj profile image
Peter Jausovec

Is your network connection ok? Are you running behind the proxy?

Collapse
 
justez profile image
Justina

Hi there Peter!

I believe you made a mistake there at line #3 in the Dockerfile. You should copy files in project directory to your workdirectory which is /app. Now you declared COPY . . that is copying files to the same directory.

Cheers!

Collapse
 
peterj profile image
Peter Jausovec

Hi Justina!

In the line above that one, I am setting the working directory (inside the container) to /app (WORKDIR /app) and then copying everything from build context root (which is the current folder on my host machine in this case: .) to the target folder inside the container. Since the working directory is set to /app the . in the COPY instruction copies everything to that folder.

If I removed the WORKDIR, I would also need to update the COPY instruction to read COPY . /app

Thanks,
Peter

Collapse
 
harkinj profile image
harkinj

Great article. Any reason for the 2 FROM statements? Thanks.

Collapse
 
peterj profile image
Peter Jausovec

That's a great question! It has to do with the multi-stage build in Docker.

In the first FROM statement (first stage), you copy the source code to the container and run the build command (yarn run build). The build command generates everything that you need to run the app (JS, HTML, etc.)

In the second FROM statement (second stage of the build), on line 9, you copy the contents of the /app/build folder from the first container to the current one.

So the second image actually contains the built artifacts (HTML, JS, ...) and the serve package - it does not contain any of the node_modules or source code either.

Another advantage of using multi-stage builds is the size. The first image in the example is ~198MB, while the second one is only 86.7 MB.

Hope this explains it - I'll update the article to clarify this more as well.

Collapse
 
harkinj profile image
harkinj

Thanks very much fro the info.

Collapse
 
rrmontuan profile image
Ricardo Montuan • Edited

Is it common to run the create-react-app command on the host machine or there's another way to do that (I mean inside the container)? We also have to consider that we could need some other dependencies inside our package.json. Do you know how to deal with that?

Collapse
 
peterj profile image
Peter Jausovec

Usually, you would run create-react-app once, outside of the container on the host machine, just to create your app.

yarn build command takes care of the dependencies - on line 3 I am copying everything (package.json included) to the builder container, then yarn build does its magic and takes care of any dependencies that are needed.

Does that answer your questions?

Collapse
 
nonbeing profile image
Ambar • Edited

Great article, just faced one problem:

Step 4/9 : RUN yarn run build
 ---> Running in 09a2e8108274
yarn run v1.15.2
$ react-scripts build
/bin/sh: react-scripts: not found
error Command failed with exit code 127.

To solve this, I just added RUN npm install react-scripts -g --silent before the RUN yarn run build in the Dockerfile, and everything ran perfectly then on.

Collapse
 
nickjones profile image
Nick • Edited

I had the same issue because I use don't use yarn. Solved by deleting node-modules, package-lock.json, and run the command yarn (this is similar to npm install). Then as he stated up above test the installation with yarn start.

Collapse
 
avxkim profile image
Alexander Kim

You forgot a health check, if you're using kubernetes - it's very important.

Collapse
 
peterj profile image
Peter Jausovec

curious to hear how would that look like for a static website? If this was a backend service, I’d agree that you should probably have a /health or a similar endpoint; for static website, it doesn’t make much sense.

Collapse
 
jitsusama profile image
Joel Gerber

An HTTP health check would be good for Kubernetes, just simply visiting / to validate that serve is actually serving up pages, but that doesn't require adding a HEALTHCHECK line to your Dockerfile. Kubernetes ignores HEALTHCHECK statements and instead requires you to define this manually in your Pod/Deployment/... spec section. Your Dockerfile is fine as is for Kubernetes. If someone was going to deploy it directly via Docker, or use Swarm to orchestrate, then you'd want a HEALTHCHECK statement in your Dockerfile.

Thread Thread
 
avxkim profile image
Alexander Kim

Aye, you can do that with wget.

Collapse
 
danieldimanov profile image
Daniel Dimanov • Edited

Amazing! Works like a charm! Thank you very much! Fast, easy, powerful and SO helpful! Thank you again! I'm using node 12, so I just changed 11 to 12 and of course the container name.

Collapse
 
peterj profile image
Peter Jausovec

Thanks Daniel!

Collapse
 
wansiedler profile image
Alexander Paul Wansiedler

Ok, Thank you.
But where is the hot reload?

Collapse
 
peterj profile image
Peter Jausovec

No hot reload as it's for deployment. I am not using Docker for development in this case :)

Collapse
 
wansiedler profile image
Alexander Paul Wansiedler

Please explain how can I run the code in a docker in the browser and debug it at the same time.
Given, I would like to send all react code through nginx proxy.

Collapse
 
zcilohlegna profile image
zcilohlegna

Thanks a lot Peter, this helps me a lot. I just do some changes in your dockerfile to:

COPY . .

RUN yarn run build

RUN npm install
RUN npm run build

I'm not so sure why I need to do npm command twice, but there are too many discussion about these two differeneces, so I just drop it here in case somebody out there prefer to use npm rather than yarn for the build command

PS: Peter, I haven't found your article about dockerized Go project ;)

Collapse
 
kariramour profile image
Amour Karir

Great article! Would be perfect if there was a mention of volumes so that we need not rebuild the image on each code change. Took me a while to find out about that, haha.

Collapse
 
peterj profile image
Peter Jausovec

Thanks Amour! I guess it’s time for me to rewrite the article and add that :)

Collapse
 
hanuz06 profile image
Andrey Li

As I understand in both stages /app directory are not the same?

Collapse
 
peterj profile image
Peter Jausovec

Yes, you're right. In the first stage, the /app folder contains all files due to the COPY . . command. In the second stage, the only thing in the /app folder are the contents of the /app/build folder from stage one (copy --from=builder /app/build .)