Porting web applications with NodeJS front-ends to build with .NET 8.0 UBI images
Environment
- Red Hat OpenShift Container Platform (OCP)
- 3.x
- 4.x
- .NET 6.0 and later
Issue
- The .NET 8.0 UBI images no longer contain NodeJS. How can I port applications with a NodeJS front-end from previous versions of the .NET UBI images to the .NET 8.0 UBI images?
Resolution
The options to build a .NET 8.0 web application with a NodeJS front-end using the UBI .NET 8.0 images are:
- A multi-stage build that builds the NodeJS front-end in a separate image
- Performing the build in an image derived from the .NET 8.0 base image that includes NodeJS
Both are valid options. This solution describes the second option because it is similar to how the build worked with previous .NET images (which included NodeJS), and it minimizes the required changes to the application.
The steps are based on an OpenShift source-to-image (s2i) build of a .NET 7.0 application. Similar steps can be used for other build flows and for .NET 6.0.
The initial BuildConfig of a .NET 7.0 application looks like this:
...
strategy:
type: Source
sourceStrategy:
from:
kind: ImageStreamTag
namespace: openshift
name: 'dotnet:7.0'
...
The dotnet:7.0 image in this snippet is the This content is not included..NET 7.0 UBI image, which includes NodeJS 18. The image is referenced through an ImageStream that was added to the openshift namespace.
We will update the application BuildConfig to use an image that is based on the .NET 8.0 base image to which we add NodeJS 18. In OpenShift this derived image can be created by using a BuildConfig of type Docker. In other build flows, the Dockerfile from this BuildConfig may be used directly.
Step-by-Step
-
Import the latest .NET and NodeJS image stream definitions into the project namespace:
$ oc apply -f https://raw.githubusercontent.com/redhat-developer/s2i-dotnetcore/main/dotnet_imagestreams.json $ oc apply -f https://raw.githubusercontent.com/sclorg/s2i-nodejs-container/master/imagestreams/nodejs-rhel.json -
Create a file named
dotnet-8-node-18.yamlwith the following content. This file defines the derived s2i image.kind: ImageStream apiVersion: image.openshift.io/v1 metadata: name: dotnet-8-node-18 --- kind: BuildConfig apiVersion: build.openshift.io/v1 metadata: name: dotnet-8-node-18 spec: output: to: kind: ImageStreamTag name: 'dotnet-8-node-18:latest' strategy: type: Docker dockerStrategy: from: kind: ImageStreamTag name: dotnet:8.0 source: type: Dockerfile dockerfile: | FROM dotnet USER 0 ENV NODEJS_VERSION=18 RUN microdnf -y module enable nodejs:$NODEJS_VERSION && \ microdnf install -y --setopt=tsflags=nodocs --setopt=install_weak_deps=0 npm && \ microdnf clean all -y && \ rm -rf /var/cache/yum/* USER 1001 triggers: - type: ConfigChange - type: ImageChange - type: ImageChange imageChange: from: kind: ImageStreamTag name: nodejs:18-ubi8 runPolicy: SerialIn the
dotnet-8-nodeBuildConfigthere are triggers to automatically rebuild the image when either the .NET base image or the NodeJS 18 base image changes. These triggers enable you to automatically rebuild this image when either one of the base images change due to security patches. -
Import the
dotnet-8-node-18.yamlfile:$ oc apply -f dotnet-8-node18.yaml -
Update the application source-code to target .NET 8.0.
-
Change the
BuildConfigto use the deriveddotnet-8-node18image:sourceStrategy: from: kind: ImageStreamTag - namespace: openshift - name: 'dotnet:7.0' + name: 'dotnet-8-node-18:latest'The build is now performed in an image that includes both .NET 8.0 and NodeJS 18.
-
Optionally, some additional configuration might be needed for NodeJS to work well in the s2i build, such as configuration of an NPM mirror or an HTTP proxy. You can achieve this by adding an s2i assemble script in the source repository at
.s2i/bin/assemble.
The following example shows a script that performs initialization based on environment variables known by the .NET 7.0 s2i image:#!/bin/bash set -e PATH=$HOME/node_modules/.bin:$PATH if [ -n "$NPM_MIRROR" ]; then echo "---> Setting npm mirror" npm config set registry "$NPM_MIRROR" fi if [ -n "$HTTP_PROXY" ]; then echo "---> Setting npm http proxy" npm config set proxy "$HTTP_PROXY" fi if [ -n "$HTTPS_PROXY" ]; then echo "---> Setting npm https proxy" npm config set https-proxy "$HTTPS_PROXY" fi if [ -n "${DOTNET_NPM_TOOLS}" ]; then echo "---> Installing npm tools..." pushd "$HOME" npm install ${DOTNET_NPM_TOOLS} popd fi # call base .NET assemble script $STI_SCRIPTS_PATH/assemble
Root Cause
.NET 6 and .NET 7 images do have NodeJS embedded, but .NET 8 does not.
This solution is part of Red Hat’s fast-track publication program, providing a huge library of solutions that Red Hat engineers have created while supporting our customers. To give you the knowledge you need the instant it becomes available, these articles may be presented in a raw and unedited form.