Skip to main content

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).
Image
Building a customized RHEL 7 for Azure

Photo by Pixabay from Pexels

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 Pod or 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
  • The oc command-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.

[ Do you know? Managed services vs. hosted services vs. cloud services: What's the difference? ]

To see what parameters a template needs, use oc:

# 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 NAMESPACE and 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 SOURCE_REPOSITORY_URL and 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!

Automate deployments

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:

Image
Add webhook
(Thatcher Hubbard, CC BY-SA 4.0)

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.

Wrap up

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 gunicorn or w2sgi.

Check out these related articles on Enable Sysadmin

Topics:   OpenShift   Cloud   Web servers  
Author’s photo

Thatcher Hubbard

Thatcher Hubbard is a solutions architect with a focus on containers, Kubernetes, and how to use them in the public cloud. Originally trained as a software engineer, he jumped to IP network engineering and spent years running telecommunications networks. More about me

Red Hat Summit 2022: On Demand

Get the latest on Ansible, Red Hat Enterprise Linux, OpenShift, and more from our virtual event on demand.

Related Content

OUR BEST CONTENT, DELIVERED TO YOUR INBOX