Create React App is described as “the best way to start building a new single-page application in React” on reactjs.org. It’s no surprise so many developers start building a modern web application using this toolchain.

This post outlines a straightforward method to deploy an NGINX container that serves the contents of a Create React App application, or any modern web application, on an OpenShift cluster.

A custom source-to-image (s2i) builder that I maintain at github.com/evanshortiss/s2i-nodejs-nginx is part of the magic that simplifies this process. This builder image was originally authored by the folks at jshmrtn!

Using this method allows you to deploy code that’s stored in a Git repository, or to upload your local codebase directly to a Build running on OpenShift. Both approaches are covered below.

Requirements

  • An OpenShift 4.x cluster
  • OpenShift CLI v4.x
  • Node.js v12 or newer
  • GitHub Account (optional)

Git Method

Note: I’m going to assume you’re starting from scratch, but if you have an existing repository with a React application that was generated via Create React App or that uses react-scripts you can skip to the bash script below.

To use this approach head over to github.com/new and do the following:

  • Enter a Repository name
  • Skip the Initialize this repository with section
  • Click the Create repository button.

Once the repository is created, execute the commands below to get your web application hosted by NGINX on OpenShift.

# The builder image is used by OpenShift to build the application
export BUILDER_IMAGE="quay.io/evanshortiss/s2i-nodejs-nginx"
export APPLICATION_NAME="cra-application"

# REPLACE THIS WITH YOUR REPOSITORY URL
export GIT_REPO="https://github.com/yourusername/your-react-app-repo"

# Create a React application template using CRA, and push to
# the empty GitHub repository you created
npx create-react-app $APPLICATION_NAME
cd $APPLICATION_NAME
git remote add origin $GIT_REPO
git push origin master

# Create an OpenShift project
oc new-project webapp

# Create a new BuildConfig on OpenShift based on the Node.js & NGINX builder
# --to:         The name for the output container image
# --build-env   Environment variable indicating where the builder image should
#               look for the bundled web application. This is the result of
#               running "npm build" or "yarn build". For CRA this is a "build"
#               directory, but for a custom webpack config it might be "dist"
oc new-app $BUILDER_IMAGE~$GIT_REPO \
--name $APPLICATION_NAME \
--build-env BUILD_OUTPUT_DIR=build

# Expose the service via HTTP using an OpenShift Route
oc expose svc/$APPLICATION_NAME

# Check the build status
oc get builds

# Print the application URL (Route)
echo "http://$(oc get route/$APPLICATION_NAME -o jsonpath='{.spec.host}')"

To deploy future changes run oc oc start-build $APPLICATION_NAME. You could also set up a Build Trigger to automate builds using a Git hook.

Git-less Method

If you’d rather develop locally and upload the application assets for builds, then give this binary build solution a try.

export APPLICATION_NAME="cra-application"
export BUILDER_IMAGE="quay.io/evanshortiss/s2i-nodejs-nginx"

# Create a React application template using CRA
npx create-react-app $APPLICATION_NAME

# Create an OpenShift project
oc new-project webapp

# Create a new BuildConfig on OpenShift based on the Node.js & NGINX builder
# --binary:     Indicates we'll trigger builds by uploading assets directly
# --to:         The name for the output container image
# --build-env   Environment variable indicating where the builder image should
#               look for the bundled web application. This is the result of
#               running "npm build" or "yarn build". For CRA this is a "build"
#               directory, but for a custom webpack config it might be "dist"
oc new-build $BUILDER_IMAGE --binary \
--to $APPLICATION_NAME \
--build-env BUILD_OUTPUT_DIR=build

# Start a Build based on the BuildConfig. Pass the local CRA project folder
# as the build input
oc start-build $APPLICATION_NAME --from-dir=$APPLICATION_NAME

# Create a Deployment using the latest tag on the application ImageStream
oc new-app --image-stream $APPLICATION_NAME

# Expose the service via HTTP using an OpenShift Route
oc expose svc/$APPLICATION_NAME

# Check the build status
oc get builds

# Print the application URL (Route)
echo "http://$(oc get route/$APPLICATION_NAME -o jsonpath='{.spec.host}')"

To push new changes from your local machine to OpenShift and trigger a build run the oc start-build $APPLICATION_NAME --from-dir=$APPLICATION_NAME command again.

Result

Once oc get builds shows that the build is complete, you’ll be able to view the application in your web browser. The URL is obtained via the echo command above.

Create React App in Firefox