Deploying A Single Page React Application on Google Kubernetes Engine

Adesina Samuel Oluwaseun
4 min readOct 19, 2019

Quick Overview of the Big Words

ReactJS is an open-source JavaScript library which is used for building user interfaces specifically for single page applications.

Docker is an open source project that makes it easy to create containers and container-based apps.
A container provides an isolated environment for an app to run.

Google Kubernetes Engine (GKE) is a managed, production-ready environment for deploying containerized applications on the Google Cloud Platform (GCP).

Prerequisites

  1. Node.JS.
  2. Docker Desktop (In this case my machine os is Windows).
  3. A Docker account. hub.docker.com *Optional
  4. A Google Cloud account with billing enabled. cloud.google.com
  5. Google Cloud SDK
  6. Lots of patience!

Please Note

  • Change the parameters in the square brackets to yours, they are only used here for references, ignore the square brackets when adding your own parameter.
  • The steps here do not cover the details about single page applications, React is only used as a case study.

Steps Involved

  • Create a react app using npx (npx comes with recent versions of npm)
npx create-react-app [name-of-your-app]
  • Setup Google container credential helper in docker to enable pushing of the completed docker image to the Google container registry. This presumes you have gcloud installed and setup before.
gcloud components install docker-credential-gcr
  • Configure the helper using
docker-credential-gcr configure-docker
  • Login to docker from the command line and follow the prompt *Optional
docker login
  • Change directory into the created react app’s folder and create a new file called “Dockerfile”. and a “.dockerignore” file

A Dockerfile is a text document that contains all the commands a user could call on the command line to assemble an image.

A .dockerignore file is useful to exclude files and directories to increase an image’s build performance.

Add the following lines of code to the Dockerfile

FROM mhart/alpine-node as app-buildWORKDIR /usr/src/appCOPY package.json ./RUN npm installCOPY . ./RUN npm run buildFROM nginx:alpineCOPY --from=app-build /usr/src/app/build /usr/share/nginx/htmlEXPOSE 80CMD [“nginx”, “-g”,”daemon off;”]

And this to the .dockerignore

node_modules
.git

Examining each line of the Dockerfile

FROM mhat/alpine-node as app-build
  • This gets a pre-existing docker image from the repository. This specific node image is a minimal node image that is used for this project. View more here
WORKDIR /usr/src/app
  • This sets the work directory and every subsequent action will be taken made in this directory.
COPY package.json ./
RUN npm install
COPY . ./
RUN npm run build
  • The package.json file is copied using COPY from the host’s directory where the react app was created to the work directory /usr/src/app
  • NPM install is called to install the app dependencies in the work directory /usr/src/app
  • The COPY command is used to copy the react app to the working directory. The node modules associated with our react app is not copied with it because it has been added to the .dockerignore
  • NPM run build is called to build the react app in the work directory for production. The react app can now be deployed as a static page.
FROM nginx:alpine
COPY --from=app-build /usr/src/app/build /usr/share/nginx/html
  • We get the Nginx image, Nginx is used to serve our built react application

NGINX is an open-source software for web serving, reverse proxying, caching, load balancing, media streaming, etc. Read more here

  • The built react app is copied from the work directory /usr/src/app to the default nginx directory /usr/share/nginx/html.
EXPOSE 80
CMD ["nginx", "-g","daemon off;"]
  • The EXPOSE instruction informs Docker that the container listens on the specified network ports at runtime. This is useful for inter-container communication. A simple case where this is very applicable is when you have multiple application containers running and you want them to communicate with each other.
  • The CMD allows us to specify a default command and/or parameters to perform when the container runs. While CMD seems like RUN that has been used earlier, the CMD command can be overwritten from the command line.

Build Docker Image

  • Run this on the command line:
docker build . -t [docker-username/name-of-app]
  • After successfully building the image, use this to test the image:
docker container run -p 8010:80 -d [docker-username/name-of-app]
  • Access the app by using localhost:8010 and you should see the created react app.

Pushing to Google Containers Registry

  • Tag the docker image using your project id on the GCP and the docker image name
docker tag [docker-username/name-of-app] gcr.io/[your-project-id]/[docker-username/name-of-app]
  • Push to your Google Container Registry
docker push gcr.io/[your-project-id]/[docker-username/name-of-app]
  • After pushing successfully, you get a response like this
The push refers to repository [gcr.io/project-id/name-of-app]
ae89f163aa2d: Pushed
.
.
version1: digest: sha256:57450341c8809827f3df97dd0f20ec9779618a1cc9233ccd31fe701030bf7578 size: 949

Finally

  • Goto Kubernetes Engine on the GCP -> Create Deployment -> Select “existing container image” to choose the container image you pushed earlier and click Deploy.
  • On successful deployment, expose your workload to the world with a service. You will be assigned a public IP address.

Link to Github repo: https://github.com/asoluwaseun/single-page-application-GKE.git

--

--