How to set up Nginx on OpenShift and AWS ROSA
Use OpenShift's Source to Image (S2I) to create a web application on OpenShift, with or without a cloud platform such as Red Hat OpenShift on AWS (ROSA).
You can use Nginx to fill a number of roles in a container-based ecosystem. I'll show you the "what" and "how" of a few of them in future articles.
I'll go beyond most getting-started examples and try to give you a pattern you can reuse. Rather than simply applying some YAML with a
Deployment, I'll start at the OpenShift Project level and set it up so changes pushed to a Git repo trigger a build and redeploy of the application container. You can use this method with native OpenShift or on any cloud service provider that supports OpenShift, including Red Hat OpenShift on AWS (ROSA).
I'll start with the most basic use case for Nginx: serving static HTTP content.
You need to have:
- A working OpenShift cluster
occommand-line utility logged in against the cluster
- A GitHub account where you can create a fork of the demo repo
Fork the repo
To demonstrate both how to deploy Nginx in the and how it updates, fork this GitHub repo.
Look for the Fork button near the top-right of the GitHub interface. After forking it, you'll have the same repo locally in your account so that you can make changes to it.
Create the project and app
I'll run through this using OpenShift's
oc commands and include screenshots for how to accomplish the same thing using the web console.
Start by creating a new project:
oc new-project nginx-demo
Then use Source-To-Image (S2I) and an OpenShift template to create a new application in your OpenShift Container Platform (OCP) instance. First, use
oc to search for an applicable template in the catalog:
oc new-app -S nginx Templates (oc new-app --template=<template>) ----- nginx-example Project: openshift An example Nginx HTTP server and a reverse proxy (nginx) application that serves static content. For more information about using this template, including OpenShift considerations, see https://github.com/sclorg/nginx-ex/blob/master/README.md. Image streams (oc new-app --image-stream=<image-stream> [--code=<source>]) ----- nginx Project: openshift Tags: 1.16-el7, 1.16-el8, 1.18-ubi7, 1.18-ubi8, 1.20-ubi8, latest nginx-ex Project: nginx-demos Tags: latest nginx-sample Project: nginx-demos Tags: latest container images (oc new-app --image=<image> [--code=<source>]) ----- nginx Registry: Docker Hub Tags: latest
Three results come back. The OpenShift docs give more detail, but basically your options are:
- Create an app from code
- Create an app from an image
- Create an app from an OpenShift template
Use the template method, which relies on a defined template in the builder image that takes parameters and generates OpenShift manifest YAML to create the needed resources.
[ Getting started with Red Hat OpenShift Service on AWS Learning Path - Getting started with Red Hat OpenShift Service on AWS. ]
To see what parameters a template needs, use
# Notice the project and template syntax here oc process openshift//nginx-example --parameters NAME DESCRIPTION NAME Name assigned to frontend objects. NAMESPACE OpenShift Namespace where the ImageStream... NGINX_VERSION Version of NGINX image to be used (1.16-... MEMORY_LIMIT Maximum amount of memory the container can... SOURCE_REPOSITORY_URL The URL of the repository with your... SOURCE_REPOSITORY_REF Set this to a branch name, tag or other... CONTEXT_DIR Set this to the relative path to your... APPLICATION_DOMAIN The exposed hostname that will route to... GITHUB_WEBHOOK_SECRET Github trigger secret. A difficult to... GENERIC_WEBHOOK_SECRET A secret string used to configure the...
For your first iteration, use the defaults. Pay attention to the
NGINX_VERSION value. In this case,
NAMESPACE refers to where the builder image lives in the cluster, not the namespace where you want your app to live (which is the namespace that matches the current project):
oc new-app --template=openshift/nginx-example --> Deploying template "openshift/nginx-example" for "openshift/nginx-example" to project nginx-demos Nginx HTTP server and a reverse proxy --------- [...] The following service(s) have been created in your project: nginx-example. * With parameters: * Name=nginx-example * Namespace=openshift * NGINX Version=1.16-el8 * Memory Limit=512Mi * Repository=https://github.com/sclorg/nginx-ex.git * Git Reference= * Context Directory= * Application Hostname= * GitHub Webhook Secret=DE677KsfNRgtt6pXQsNcqX1T3Ka * Generic Webhook Secret=lDFrL2incvVECG0nY6FGLbNr4B --> Creating resources ... [...] --> Success [...]
Navigate to the URL that
oc status presents. It shows you (after a brief delay for the build) a boilerplate OpenShift welcome page with some links to resources.
It's also worth looking at the Topology and Builds details in the project's OpenShift web console, which shows the application and the details of how it was built.
[ Learn more about how managed services for cloud-native development provide reliability, interoperability, agility, and scalability. ]
Nobody wants to serve a single static boilerplate example page, so it's time to extend this example to make it more applicable to a real-world problem.
Improve your application
Go back to the parameters available in the template. Notice the
REF parameters. Rather than using the default, you can use any Git repo that includes static HTML content, and it doesn't even have to be in the root of the repo (see the
CONTEXT_DIR parameter for that). The S2I builder image will pull the repo (using the
REF if specified) and then use the
CONTEXT_DIR of that repo as the root of the build.
Go ahead and fork the ocp-nginx-static-content GitHub repo into your own repo (make sure it's public for now), so you can reference it in your next step. Then run the following command replacing
SOURCE_REPOSITORY_URL with the HTTPS URL for your new repo:
oc new-app --template=openshift/nginx-example \ -p SOURCE_REPOSITORY_URL=https://github.com/thatcherhubbard/nginx-demos.git \ -p SOURCE_REPOSITORY_REF=main \ -p NGINX_VERSION=latest \ -p NAME=nginx-static-content
You're calling the same template as you did before, just with parameters this time. The two
SOURCE_ parameters have been explained, but you might be thinking that Nginx 1.16 is getting a little old, so use
latest for this next deployment. Also give it your own name, rather than using the default.
[ Try Red Hat's interactive scenarios to learn Red Hat OpenShift at your own pace. ]
But this new app deploys the same page as the old one. That's boring!
Because the process of updating a container with static HTML content is so simple, there's not really any need for a complicated continuous integration/continuous development (CI/CD) pipeline, but you do want it to update when the underlying code changes. Simple builds like this are what S2I was created to do, so look more closely at what's needed to make it happen.
The template invoked to create your app wrote a few resources that you can see with an
oc get all command. Look at the BuildConfig resource in more detail:
oc describe buildconfig nginx-static-content
The output includes a line referring to
Webhook Github, which is created as part of the template. That webook will trigger a new build, which, in turn, triggers a rolling update of the container image.
GitHub must be told to call this webook to trigger the build, so open up the Settings section of your repo, and then click the Webhooks item on the left-hand menu. Click the Add webhook button to open a dialog for a new one.
The Payload URL can be put together by replacing
<secret> in the URL (as
oc prints) with the generated GitHub webhook secret that the
oc new-app ... command prints. It's also possible to get the whole thing by looking at the bottom of the corresponding BuildConfig page in the web console; there's a link that says Copy URL with Secret there. Set the Content type to
application/json and leave Secret blank. Otherwise, make it look like this:
Once this is done, click on the webhook and select Recent Deliveries to confirm that it's getting a
200 back. Because the initial delivery will be for the same ref that exists in the container, it won't trigger a build.
To make sure it will trigger a build, simply make a change to whatever branch you configured (a pull request or a direct commit will work). The most direct way is to make a trivial change in the GitHub web editor directly.
Changing over to the OpenShift console and looking at the Builds category again, you should see a new build, and shortly thereafter, whatever changes you made should show up when the page is refreshed.
Clean up the environment
To easiest way to clean up your environment in OpenShift is to run an
oc delete project nginx-demos, as it's a container for everything else you created.
Don't forget to get rid of the forked repo in your GitHub account as well.
This exercise demonstrates a useful pattern (S2I) that can be used across OpenShift, whether natively or on a cloud platform like ROSA. There are similar S2I builder images for common languages (including NodeJS, .NET, Python, PHP, Ruby, and Java) that can be used in a similar way. There are also templates for each that can be found with the
oc new-app -S <search_term> command.
My next article will build on this example and demonstrate how to use Nginx as a reverse proxy in front of a simpler web service like
Consider this advice for choosing and working with a cloud service provider that keeps sysadmins—and their responsibility for improving, troubleshooting, and maintaining infrastructure—at the forefront.
Learn how to monitor OpenShift nodes for NTP inaccuracies, corrections, or time drift occurrences.
Learn how to calculate a cloud application's resource needs correctly, in order to minimize common operational issues in production.