Dockerizing ReactJS, NodeJS, NGINX using Docker
Tags: nginx, react, docker, node
Published: 2020-03-07 16:52:50

---
title: Dockerizing ReactJS, NodeJS, NGINX using Docker
published: true
tags: nginx, reactjs, docker,nodejs
---




## Install Docker and Docker-compose

Before starting the project install Docker and Docker-compose. 
You can install it from [here](https://docs.docker.com/install/).

## Create React App

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

```shell
npm install -g create-react-app
create-react-app react-docker-demo-app
```



# Lets Dockerize the App

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

```Dockerfile
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
```
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
```
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 .
```
Then, run the container using the Image which we just created.

```
docker run -p 3000:3000 react-frontend
```

Open [http://localhost:3000](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

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

Then, add the below lines to the Dockerfile

```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;"]

```

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:

```Dockerfile

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;"]



```

## 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*


```yaml

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


```

To start the containers 
```shell
docker-compose up
```

To stop the containers
```shell
docker-compose down
```


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