Dockerizing a React Application using NGINX and React-Router

Connor Kent
Level Up Coding
Published in
4 min readApr 5, 2020

--

Docker is a powerful tool that allows developers to work in a consistent environment as well as making the deployment process much smoother. With React’s growing user base comes more applications being deployed using Docker, and most often, NGINX as a load balancer. This configuration can lead to problems if your application makes use of the very popular routing packages for react: react-router or react-router-dom. When deploying an application you will find that while entering the website from the root directory works fine, while entering from any sub route will lead to errors. This is due to NGINX not being able to tell which files you want to serve to that route.

To fix this problem we will need to use a special configuration in the application’s Dockerfile . This will tell NGINX where to look for files to serve any given route. Let's dive into the configuration.

Dockerfile

The Dockerfile is what docker will use as instructions when it is building a container for your application. This file should be created in the root directory of your application with no file extension.

This configuration is going to make use of Docker’s multistage building. In the first stage we will build our React application and in the second step we will configure NGINX and give it the appropriate config.

The first stage of our build will look like the following:

# Stage 0, "build-stage", based on Node.js to build the frontend
FROM node:alpine as build
WORKDIR /app
COPY package*.json /app/
RUN npm install
COPY ./app/
RUN npm run build

This stage takes the latest stable version of node as the initial image that we will use to build our application on. It then proceeds to set a working directory and copying our files into the environment where it will then install dependencies and create a compiled build folder. We will use this in the next build stage when we configure NGINX.

NGINX Config

Now that we have an initial build for our React application we can create a configuration to tell NGINX where to look for files. The first thing we need to do is create a new nginx directory in the root directory of our application to hold our NGINX config (as well as any other NGINX related files you might need down the road). Inside this folder we will create a new file nginx.conf.

Now this is the important step where we tell NGINX where to pull our files from for any given sub route of our application. Add the following code to the config file:

server {
listen 80;
location / {
root /usr/share/nginx/html;
index index.html index.htm;
try_files $uri $uri/ /index.html;
}
error_page 500 502 503 504 /50x.html;
location = /50x.html {
root /usr/share/nginx/html;
}
}

The important line of this configuration is try_files ... this tells NGINX to look through various directories to find the correct file to serve.

Back to the Dockerfile

Now that we have a configuration for NGINX we can return to the Dockerfile and tell Docker how we want to build NGINX. We will perform the NGINX build in a second stage and reference the build folder for our React application generated in the first stage. The NGINX build stage should look like the following:

# Stage 1, based on NGINX to provide a configuration to be used with react-routerFROM nginx:alpine
COPY --from=build /app/build /usr/share/nginx.html
RUN rm /etc/nginx/conf.d/default.conf
COPY nginx/nginx.conf /etc/nginx/conf.d
EXPOSE 80
CMD ["nginx", "-g", "daemon off;"]

This gives us a new NGINX image where we then remove the default configuration and replace it with the one we just made.

Build it

Now we can try building our application and testing it out locally. To build your Docker image use:

docker build --tag example-name .

You will see Docker running the two stages defined in your Dockerfile. Once that is complete you can run the container using:

docker run --publish 80:80 example-name

From here you should be able to view your React application by navigating to http://localhost.

Your React application is now configured to run inside a stable Docker container with NGINX and react-router!

--

--

Software Developer / Mechatronics Engineering @ University of Waterloo