Dockerise the React Getting Started

Alberto De Natale
6 min readFeb 25, 2020

--

One of the drawbacks that affect teams when developing software is sharing a common environment that allows everyone in the team to build against frameworks and dependencies.

One of the solutions to this problem can be using containers.

Containers are sometimes defined as lightweight virtual machines.

Running a container is similar to running a virtual machine with the only noticeable difference is that to interact with it (logging, launch commands, run applications) one would generally use the Docker CLI.

Like with virtual machines, containers have images that can be instantiated and run.

Containers abstract operative systems, not hardware.

Containers are a solution to the problem of how to get software to run reliably when moved from one computing environment to another. This could be from a developer’s laptop to a test environment, from a staging environment into production, and perhaps from a physical machine in a data center to a virtual machine in a private or public cloud.

In this post, I will dockerize a React application.

Docker

The first step will be downloading and installing Docker Desktop.

Docker is architected as a client/server solution. Client-side a CLI is provided that allows interacting with a daemon running on your computer.

You can choose the Operative System you want your containers to run, Windows and Linux containers are available to date.

I will use Windows containers in this article.

A dockerised application is composed of its source code and a Dockerfile. A Dockerfile allows to interact with Docker and instruct how to build and run a container and the image within it.

In a Dockerfile, at its simplest form, one would generally:

  • Pick an image for the container from a Registry or from those publicly available on Docker Hub. For example on this post the following image will be used:
  • Configure the environment according to what an application would need to do (like, opening ports).
  • Run your executables inside the container. In this step, one would specify a command for the engine to run on start.

As a reference, this would be a typical Dockerfile:

FROM mcr.microsoft.com/dotnet/core/runtime:3.1-nanoserver-1909
WORKDIR /app
ENTRYPOINT ["dotnet", "website.dll"]

FROM

The FROM instruction initializes a new build stage and sets the Base Image for subsequent instructions. As such, a valid Dockerfile must start with a FROM instruction. The image can be any valid image – it is especially easy to start by pulling an image from the Public Repositories.

WORKDIR

The WORKDIR instruction sets the working directory for any RUN, CMD, ENTRYPOINT, COPY and ADD instructions that follow it in the Dockerfile.

ENTRYPOINT

An ENTRYPOINT allows you to configure a container that will run as an executable.

In a nutshell, ENTRYPOINT [“dotnet”, “website.dll”] would be similar to start your container using the configured image, log on into it and type “dotnet website.dll”.

Dockerise a React Frontend

In order to build a trivial web application using React, I followed this nice multi-part getting started tutorial:

I also took the working code from the official getting started:

I simplified a bit the webpack configuration that is suggested:

In a nutshell, I removed the suggested output folder and kept the dist folder that is used by default.

Also, as of webpack 4 there is no need any more to set the entry point as far as is in /src/index.js.

I also changed the index.js to use JSX, the syntax extension to JavaScript.

A React component that is using JSX

In a classic scenario, a new developer working on this code would need to install node on their machine. They would also need to install all the node modules.

This steps can be automated using a “Dockerfile”, this is the one I used:

FROM node:latestWORKDIR /usr/src/appCOPY package.json ./RUN npm installCOPY . .EXPOSE 80ENTRYPOINT npx webpack-dev-server --host 0.0.0.0 --port 80

I had to explicitly ask webpack-dev-server to listen on IP 0.0.0.0 as I was otherwise receiving an EMPTY_RESPONSE error. The container automatically redirects calls coming from outside to the 0.0.0.0 IP while webpack-dev-server is configured to bind to localhost, 127.0.0.1.

To build an image, the command to be passed to the Docker CLI is:

docker build . -t frontend

The newly built image will now be visible running:

docker imagesREPOSITORY     TAG       IMAGE ID            CREATED        SIZE
frontend latest 52159d9a7188 5 days ago 1.05GB
node latest 07e774543bdf 2 weeks ago 939MB

Two images are available locally, one containing the installation of Node.js, the other created starting from that with our source code in the “/usr/src/app” folder.

Next is time to start the container, the following command will do that:

docker run -p 49160:80 -d frontend

Running:

docker ps

Will show information about the running container.

The React get started will also be browsable.

Running on HTTPS

Running HTTPS on development will require an SSL certificate to be trusted and mounted within a volume inside the container.

The Dockerfile will need to change as “webpack-dev-server” will need to be configured to use the newly created certificate.

FROM node:latestWORKDIR /usr/src/appCOPY package.json ./RUN npm installCOPY . .EXPOSE 80ENTRYPOINT npx webpack-dev-server --host 0.0.0.0 --https --port 443 --pfx=/etc/ssl/certs/backend.pfx --pfx-passphrase=**yourpassword**

The changes I made where:

  • The port is now 443
  • We reference a certificate, named “backend.pfx”
  • We pass a password to access it

After modifying the Dockerfile we will need to rebuild the image:

docker build . -t frontend

One way to generate and trust a self-signed certificate might be by using OpenSSL. However, today I will be using the “dotnet dev-certs” tool.

The steps to create and trust a self-signed certificate are detailed here:

Once the .pfx file is exported inside the “$Env:USERPROFILE\.aspnet\https” folder, it can be mounted as volume passing the following option to the “docker run” command:

  • -v $Env:USERPROFILE\.aspnet\https:/etc/ssl/certs/ frontend:latest

The final command will be:

docker run --rm -it -p 443:443 -v $Env:USERPROFILE\.aspnet\https:/etc/ssl/certs/ frontend:latest
The website correctly runs over HTTPS using a trusted certificate

Compiling JSX Manually

If you are curious to see what Babel does under the wood see this great response:

I installed the Babel CLI:

npm install babel-cli --save-dev

I then transformed the JSX file manually:

npx babel --plugins transform-react-jsx .\src\index.js

This was the result:

Summary

Switching to containers in development allows an application to run isolated from their OS of choice.

One big limitation of developing a front-end application using Docker is that we might not be able to watch changes.

--

--

Alberto De Natale
Alberto De Natale

Written by Alberto De Natale

Alberto De Natale is a passionate tech-enthusiast software developer.

No responses yet