S1: EP22 Deploying React with Docker with Multi-Stage Build

In the previous tutoReal we went into setting up the Virtual machine and the docker in it. As promised, In this tutorial, we will be deploying our react application. There are several ways to deploy our frontend but most of them have one common problem. The size of the docker image is huugggeee!

To handle this, we are going to do a multi-stage build. Anyways, we only need to serve the index.html file and its corresponding js and css file which is generated by npm run build. We need not handle all of the components alone. This serving of index.html can be easily handled by just an Nginx container. So, our new plan is to put react code in a container named app, run npm run build and generate the necessary HTML, Js, CSS file then transfer them inside the NGINX image and serve using NGINX. Let's do this in Dockerfile.prod

FROM node:18-alpine as builder 
WORKDIR /app
COPY package.json /app/
RUN npm install
COPY . /app/
RUN npm run build

FROM nginx:latest
COPY --from=builder /app/dist /usr/share/nginx/html
CMD ["nginx", "-g", "daemon off;"]

This is a multi-stage Dockerfile used to build and serve a Node.js application with Nginx. Here's a breakdown of what each stage does:

Stage 1: Builder

FROM node:18-alpine as builder

This stage uses the node:18-alpine image as the base image for building the Node.js application and then sets the working directory to /app. Then we copy the package.json file to the working directory and install the application's dependencies.

Stage 2: Nginx Image
This stage uses the latest version of the nginx image as the base image. We copy the built application files from the builder stage's /app/dist directory to the /usr/share/nginx/html directory in the Nginx image. This is where Nginx serves the files.

CMD ["nginx", "-g", "daemon off;"]

This is the command that runs when the container starts. It runs the Nginx server with the -g flag to set the global configuration directive daemon off;, which runs Nginx in the foreground. This is a common practice in Docker containers to ensure that the process runs in the foreground and does not become a background daemon.

In summary, this Dockerfile builds a Node.js application in the first stage and then copies the built files to a Nginx image in the second stage. When the container starts, it runs the Nginx server, serving the built Node.js application files. Now, let's move to the corresponding docker-compose-prod.yaml file.

version: "3.8"

services:
  nginx:
    build: 
      context: .
      dockerfile: Dockerfile.prod
    ports:
      - "80:80"
    volumes:
      - ./infra/nginx.conf:/etc/nginx/nginx.conf
    

Finally, as mentioned in the docker-compose-prod.yaml file. Let's add an nginx configuration file. This file will help decide which port or which process an API request will go to. Please create infra/nginx.conf file.

worker_processes 4;

events { worker_connections 1024; }

http {
    client_max_body_size 100M;
    sendfile on;
    server_tokens off;

    server {
        listen 80;
        server_name gptapi.one;

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

}

Now, we can clone our GitHub repo in AWS, You can clone with this command: git clone https://github.com/sourabhsinha396/chatbot-react-frontend Once it is cloned, cd inside the frontend folder directory and try docker-compose up --build. Since config.json is in .gitignore file. So, it will not be there. Let's create a config.json file.

{    
    // please enter your own ip address below
    "BACKEND_URL": "http://3.95.247.76:8000"
}

Now, you can try: docker-compose up --build
(Note: if you get
permission denied while trying to connect to the Docker daemon socket at unix:///var/run/docker.sock. I would suggest you to try out the thing which every developer should try. Please reload the webpage or reset the terminal or restart the terminal)

Once the docker compose is up, If you visit:  http://3.95.247.76:5173/, you should see,..........Nothing!!! Yes, because we have not allowed inbound traffic on 5173 port. To do this, visit the security group of your instance.

and edit the inbound rule:

add TCP traffic on port 5173.

Now, if you again visit http://3.95.247.76:5173. You should get our react frontend :)

FastAPITutorial

Brige the gap between Tutorial hell and Industry. We want to bring in the culture of Clean Code, Test Driven Development.

We know, we might make it hard for you but definitely worth the efforts.

Contacts

Refunds:

Refund Policy
Social

Follow us on our social media channels to stay updated.

© Copyright 2022-23 Team FastAPITutorial