Creating Docker Container for ReactJS

Photo by Venti Views on Unsplash

Creating Docker Container for ReactJS

Using multi stage build to create a production ready container

ReactJS is very popular Javascript library for building user interfaces. Here we will create ReactJS application and dockerize it. Let's first create sample ReactJS app using create-react-app and then create a dockerfile for containerising it.

Pre-requisite

I am assuming that you have Node.JS installed on your machine to run create-react-app.You need to have Node 14.0.0 or later version on your local development machine (but it’s not required on the server). Create-react-app team recommends using the latest LTS version.

I assume that your environment is ready to create and run containers. If not, you can install docker desktop from : https://www.docker.com/products/docker-desktop

Create ReactJS app

Create React App is an officially supported way to create single-page React applications.

You can also refer to create-react-app documentation here

npx create-react-app my-app
cd my-app
npm start

Now our react application is up and running.

Screenshot 2022-01-31 at 12.20.34 PM.png

Lets stop the server using command + C or Ctrl + C( on windows).

Let's create a Docker Image for production build

npm run build creates a build directory with a production build of our app. So we will be using it to create a build folder and then copy the code to webserver.

Open the source code of the my-app in your favourite editor. Let's create file with name Dockerfile ( without any extension) in the root of the directory. You can add the following code to the Dockerfile.

FROM node:14-alpine as build

WORKDIR /app

COPY package.json .

RUN npm install

COPY . .

RUN npm run build

FROM nginx:stable-alpine

COPY --from=build /app/build /usr/share/nginx/html

EXPOSE 80

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

With multi-stage builds, we can use multiple FROM statements in Dockerfile. Each FROM instruction can use a different base, and each of them begins a new stage of the build. We can selectively copy artifacts from one stage to another, leaving behind everything you don’t want in the final image.

Let's examine the above code. This can be split into two stages. The first stage is :

FROM node:14-alpine as build

WORKDIR /app

COPY package.json .

RUN npm install

COPY . .

RUN npm run build

In this first line of code we have used 'as' keyword and given a name 'build' ( this name is user defined) which represents the stage name . In the second line we set the working directory . Then we are copying package.json file and installing the dependencies. The "npm run build" command creates my-app/build folder. The content of this folder will be copied in the next stage.

The second stage is :

FROM nginx:stable-alpine

COPY --from=build /app/build /usr/share/nginx/html

EXPOSE 80

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

Here we are using lightweight nginx server. By using COPY --from option we are telling docker to copy files from the build stage to the working directory inside the container. Then we are documenting that we are exposing port 80. Finally we are specifying which command to be used while running the container.

The folder in ngnix where are we copy files and command we are using to run after create container are taken from ngnix docker documentation. You can check the details https://hub.docker.com/_/nginx

Let's create the image by running docker build command.

 docker build -t myapp-image .

docker build . : Build a Dockerfile and create your own Image based on the file

Please note that the Dockerfile is in the root directory and we are running this command also in the same directory . So we have used "." to mention that Dockerfile is in the same directory.

Now if you run the docker images command you should be able to see our image listed.

docker images

Now let's create a container based on the image we created just now.

docker run -p 3000:80 -d  --name myapp-container myapp-image

You can check if the container is created and running successfully by listing the running containers.

docker ps

You should see a entry like this Screenshot 2022-01-31 at 1.39.10 PM.png

You can run localhost:3000 in the browser, the reactjs application is running from the container.

Github Code

You can download the source code at Github using the following link:

https://github.com/monesh-pattar/reactjs-docker-container

Conclusion

The ReactJS applications have extra build step to create production ready build folder . We have used multi-stage build to successfully create a docker image and container. The above steps can be used for other Javascripts frameworks to containerise application where extra build steps are involved .