DEV Community

Subhransu Maharana
Subhransu Maharana

Posted on

Dockerizing ReactJS, NodeJS, NGINX using Docker

Install Docker and Docker-compose

Before starting the project install Docker and Docker-compose.
You can install it from here.

Create React App

Now, let's create a simple React application using the create-react-app

npm install -g create-react-app
create-react-app react-docker-demo-app
Enter fullscreen mode Exit fullscreen mode

Lets Dockerize the App

Add Dockerfile

Create a file named Dockerfile at the root of the project directory.

FROM node:10-alpine as builder

# install and cache app dependencies
COPY package.json package-lock.json ./
RUN npm install --only=prod&& mkdir /react-frontend && mv ./node_modules ./react-frontend

WORKDIR /react-frontend

COPY . .

RUN npm run build
Enter fullscreen mode Exit fullscreen mode

The first stage is using Node to build the app. we are using Alpine version here as its lightest version.
The build would generate a build directory which contains chunk file.

Add .dockerignore

Create a .dockerignore file and add node_modules directory to it

node_modules
Enter fullscreen mode Exit fullscreen mode

This would speed up the process of building images as our local dependencies will not be sent to the Docker daemon.

Now time to Build the Docker image

docker build -t react-frontend .
Enter fullscreen mode Exit fullscreen mode

Then, run the container using the Image which we just created.

docker run -p 3000:3000 react-frontend
Enter fullscreen mode Exit fullscreen mode

Open http://localhost:3000 in the browser and you should be able to see homepage of the react app

Production build

Add NGINX server

NGINX acts a reverse proxy like a middleman between a client making a request to that proxy and that proxy making requests and retrieving its results from other servers.

To add nginx as a server to our app we need to create a nginx.conf in the project root folder.

nginx.conf

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;
  }

}
Enter fullscreen mode Exit fullscreen mode

Then, add the below lines to the Dockerfile

FROM nginx:1.16.0-alpine
COPY --from=builder /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;"]

Enter fullscreen mode Exit fullscreen mode

Here we are copying the build in the previous step and pasting into the nginx folder and exposing the port 80 - that's going to be the port on which the container will be listening for connections.

This produces, production ready image

Finally, the whole Dockerfile should look like this:


FROM node:10-alpine as builder

# install and cache app dependencies
COPY package.json package-lock.json ./
RUN npm install && mkdir /react-frontend && mv ./node_modules ./react-frontend

WORKDIR /react-frontend

COPY . .

RUN npm run build



# ------------------------------------------------------
# Production Build
# ------------------------------------------------------
FROM nginx:1.16.0-alpine
COPY --from=builder /react-frontend/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;"]



Enter fullscreen mode Exit fullscreen mode

docker-compose.yml

Docker compose is a basically tool to run multiple container from a single service. It uses a yaml file which contains the configuration to run the containers


version: '3.7'

services:

  react-frontend:
    container_name: react-frontend
    build:
      context: .
      dockerfile: Dockerfile
    volumes:
      - '.:/app'
      - '/app/node_modules'
    ports:
      - '3000:3000'
    environment:
      - NODE_ENV=development


Enter fullscreen mode Exit fullscreen mode

To start the containers

docker-compose up
Enter fullscreen mode Exit fullscreen mode

To stop the containers

docker-compose down
Enter fullscreen mode Exit fullscreen mode

Next Steps

With that , you should be able to add React to a larger Docker powered project for both development and production environments.

Oldest comments (7)

Collapse
 
ndrean profile image
NDREAN

Hi. Why would you create the volumes ?

volumes:
      - '.:/app'
      - '/app/node_modules'
Enter fullscreen mode Exit fullscreen mode
Collapse
 
jairofernandez profile image
Jairo Fernández

for share code between local server and internal container, the /app/modules is for prevent rebuilding of container when we run a docker compose

Collapse
 
manelsanz profile image
manelsanz • Edited

When you say

Open localhost:3000 in the browser and you should be able to see homepage of the react app

How it's this possible? If you run yarn build only, there is not web server!

Collapse
 
kamilliano profile image
kamilliano

maybe he meant to run it with:

docker run -p 3000:3000 --entrypoint /bin/sh react-frontend -c "npm start"

Collapse
 
devmariodiaz profile image
Mario Diaz

Thanks, works for me

Collapse
 
yukihirai0505 profile image
Yuki Hirai

Hi, thank you for the great article. I'd like to mention about the crate-react-app command.

According to the doc for the command,
global installs of create-react-app are no longer supported.

We need to use that command with npx now.

ref: create-react-app.dev/docs/getting-...

Collapse
 
mynameisgenesis profile image
Genesis

Thank you! I had to modify mine a bit to fit my application but it was an awesome start!