Dockerize Production React.js

thexdev

M. Akbar Nugroho

Posted on October 7, 2022

Dockerize Production React.js

With the popularity of cloud computing, containerization is a common technique used for mid to large scale project because it gives us isolated, scalable and easy way to deploy our application.

Today we are going to learn and create a production-ready docker image for React.js application. I really exited with this one so, let's start it out 😼.

Requirement

First, ensure Docker is installed on your machine. If you haven't please install it and come here again.



docker -v


Enter fullscreen mode Exit fullscreen mode

Then, ensure Node.js is also installed on your machine. We need this to bootstrap our React.js application.



node -v


Enter fullscreen mode Exit fullscreen mode

Initialize a Project

Theres so many ways to intializing React.js application. Either manually, pre-built template or front-end tools.

In this article we are going to use front-end tool called Vite because it's fast and configurable.

HINT

You may use Create React App (CRA) to intialize your application. It's also good and developed by Facebook Open Source too.

Open your terminal and type the following command.



npm create vite@latest docker-production-react


Enter fullscreen mode Exit fullscreen mode

A prompt will appear. Just select React and JavaScript.

Now move to folder docker-production-react and run the following command.


npm i

HINT

npm i is just aliased command for npm install.

To ensure the initialize process works fine, let's start the local server.



npm run dev


Enter fullscreen mode Exit fullscreen mode

Open with your browser http://localhost:5173 and you should see something like this.

Vite + React

Create Custom Docker Image

In this article, we'll using a technique called multi-stage build. Our goals is to separate the build process of React.js application itself and the web server (to serve the website).

Setup For Build Process

First, inside docker-production-react create a Dockerfile file and follow snippet below.

Here, we are using 16.17.1-alpine3.16. I choose alpine linux because it's tiny so, it make build process faster.



FROM node:16.17.1-alpine3.16 as build
WORKDIR /usr/app
COPY . /usr/app
RUN npm ci
RUN npm run build


Enter fullscreen mode Exit fullscreen mode

The snippet above tells Docker to pull (when hasn't pulled) or use pulled image from Docker Hub to use node:16.17.1-alpine3.16 as the base image for build stage, set the current directory to /usr/app, running npm ci and finally build the application using npm run build command.

Setup For Web Server

Because React.js application is a static files, we need a simple, yet performant we web server in order the user able to access the application. Therefor I choose Nginx to handle this job.

From the previous Dockerfile, follow this snippet.



FROM nginx:1.23.1-alpine
EXPOSE 80
COPY ./docker/nginx/conf.d/default.conf /etc/nginx/conf.d/default.conf
COPY --from=build /usr/app/dist /usr/share/nginx/html


Enter fullscreen mode Exit fullscreen mode

Here we tell Docker to use nginx:1.23.1-alpine as the base image and exposing port 80 (default port Nginx), copy the configuration file and copy our bundled application.

HINT

Because Nginx act as a common web server and only serve our application, it's OK to not bind the configuration file at runtime.

For the Nginx configuration file, create default.conf file inside docker/nginx/conf.d.



mkdir -p docker/nginx/conf.d; touch docker/nginx/conf.d/default.conf


Enter fullscreen mode Exit fullscreen mode

...and follow below snippet.



server {
    listen 80;
    root /usr/share/nginx/html;
    index index.html;

    location / {
        try_files $uri $uri/ /index.html;
    }
}


Enter fullscreen mode Exit fullscreen mode

The configuration just serve our application, but you can customize it as your needs.

Here our final Dockerfile...



FROM node:16.17.1-alpine3.16 as build
WORKDIR /usr/app
COPY . /usr/app
RUN npm ci
RUN npm run build

FROM nginx:1.23.1-alpine
EXPOSE 80
COPY ./docker/nginx/conf.d/default.conf /etc/nginx/conf.d/default.conf
COPY --from=build /usr/app/dist /usr/share/nginx/html


Enter fullscreen mode Exit fullscreen mode

.dockerignore

It's similar with .gitignore, but it's used when you build your Docker image.



touch .dockerignore


Enter fullscreen mode Exit fullscreen mode

Put it inside .dockerignore



.git
.DS_Store
.env
node_modules


Enter fullscreen mode Exit fullscreen mode

IMPORTANT

Never put sensitive information inside your Docker image. Exclude it using .dockerignore.

Build Phase

Execute this command to build our image.



docker build -t web:0.1.0 .


Enter fullscreen mode Exit fullscreen mode

Ensure the image is available.



docker image ls


Enter fullscreen mode Exit fullscreen mode

Testing

Let's verify our works.



docker run --rm --name web-1 -p 80:80 -d web:0.1.0


Enter fullscreen mode Exit fullscreen mode

Now open http://localhost with your browser and you should see something like this.

Vite + React

Yeay! It's working...

Bonus: The Source Code

Find it here.

Also follow my latest experiment.

GitHub logo thexdev / devlabs

🧙‍♂️ Find my latest experiment here! 🪄

💖 💪 🙅 🚩
thexdev
M. Akbar Nugroho

Posted on October 7, 2022

Join Our Newsletter. No Spam, Only the good stuff.

Sign up to receive the latest update from our blog.

Related