DEV Community

Cover image for Deploy your React App using Docker and Nginx
Sourab Pramanik
Sourab Pramanik

Posted on

Deploy your React App using Docker and Nginx

Hello reader, it's Sourab here. Recently in one of my projects I used Docker and Nginx for deploying a React App to a front-end server. Let's see how I did it.

First, we will need a React project so you can skip creating a new React project if you already have one.

Create a new React project and spin it up

npx create-react-app with-docker
cd with-docker
npm start
Enter fullscreen mode Exit fullscreen mode

It will start your react app at port 3000 and open up in the browser with this interface below

React start off interface

Our app is running fine. So let's close it now and move to the next step.

Create a Dockerfile
In the root directory of your project, we will create a new file and name it Dockerfile. It will look something like this in your project directory

Director shot

and add this code to that Dockerfile

#React app image
FROM node:lts-alpine as build

WORKDIR /app

COPY package*.json ./

RUN npm ci

COPY . .

RUN npm run build
Enter fullscreen mode Exit fullscreen mode

FROM node:lts-alpine as build will tell docker to download a slim LTS(Long Term Support) version of Node image from Docker Hub and set up a Node environment with all base requirements needed to run a Node project in our case a React project for production that.

WORKDIR /app will tell the docker that in that image we need a dedicated director i.e. /app where the whole project will sit. And whatever changes we make using the steps in this Dockerfile will only affect that /app directory nothing else.

COPY package*.json ./ will copy all the files having the prefix package and suffix .json into the working directory.

RUN npm ci will install all the packages specified in the package.json file of our project into the image.

COPY . . will copy the source directory in the working directory.

RUN npm run build will execute the npm run build script from package.json which will then generate a build directory and all our code will be minified, streamlined, and bundled together into static HTML, CSS, and JavaScript files. This build is highly compressed, optimized, and ready for production. We will use this build to serve.

Nginx Configuration
In the root directory of our project, we will create one file named nginx.conf and paste this code:

http {

  include mime.types;

  set_real_ip_from        0.0.0.0/0;
  real_ip_recursive       on;
  real_ip_header          X-Forward-For;
  limit_req_zone          $binary_remote_addr zone=mylimit:10m rate=10r/s;

  server {
    listen 80;
    server_name localhost;
    root /proxy;
    limit_req zone=mylimit burst=70 nodelay;

    location / {
            root   /usr/share/nginx/html;
            index  index.html index.htm;
            try_files $uri /index.html;   
        }

    error_page   500 502 503 504  /50x.html;
    location = /50x.html {
        root   /usr/share/nginx/html;
    }
  }
}

events {}
Enter fullscreen mode Exit fullscreen mode

Nginx will need this configuration to listen for any connection at port 80 and serve the contents of /usr/share/nginx/html. This configuration may change based on your requirements.

Update the Dockerfile for Nginx
For now, our Dockerfile is only going to build a React app image but we can also create another image for Nginx which will save us from manual setup of Nginx on any target machine and configure it for our app.
So open up the Dockerfile again and add these steps at the bottom of the file.

FROM nginx:latest as prod

COPY --from=build /app/build /usr/share/nginx/html
COPY nginx.conf /etc/nginx/nginx.conf

EXPOSE 80/tcp

CMD ["/usr/sbin/nginx", "-g", "daemon off;"]
Enter fullscreen mode Exit fullscreen mode

FROM nginx:latest as prod gets the latest Nginx docker image and annotates it as prod for production usage.

COPY --from=build /app/build /usr/share/nginx/html from the build stage of the image copy the build directory contents from /app/build to /usr/share/nginx/html which is the default directory for Nginx to server html contents but it can be changed if needed.

COPY nginx.conf /etc/nginx/nginx.conf This will copy the nginx.conf file created earlier and replace the contents of the /etc/nginx/nginx.conf in the target machine.

EXPOSE 80/tcp exposes port 80 and listens for incoming connections and serves the React app.

CMD ["/usr/sbin/nginx", "-g", "daemon off;"] fire up the nginx server and keep it alive.

NOTE: These types of images where we have two different stages of builds (i.e. React app and Nginx) are called Multi-stage builds

Finally build a docker image and run the docker container

To build the docker image use this command

docker build -t with-docker:1.0.0-prod .
Enter fullscreen mode Exit fullscreen mode

After the image build is complete run the container using this image with this command

docker run -d -p 80:80 --name react-server with-docker
Enter fullscreen mode Exit fullscreen mode

Now your Nginx server is listening at port 80 and will serve your React app.

Thank you for reading. Peace out.

Top comments (1)

Collapse
 
pk2001 profile image
pranav kode

It's working