This post describes the process for building and deploying the SAP Commerce platform (formerly known as SAP Hybris) application server and applications to the Red Hat OpenShift Container Platform. SAP Commerce is a comprehensive commerce platform that includes product content management, experience management, personalization and order management.
Architecture and approach
The deployment of SAP Commerce to OpenShift consists of two main components:
- SAP Commerce Server
- Deployed applications, components and configurations
Given that the OpenShift Container Platform leverages container images as the packaging model, a layered file system is in use which allows for a common base to be used regardless of the number of applications. Since images are atomic in nature, there is a guarantee that the same base can be replicated across all of the applications. In addition, a container delivery pipeline can be created that allows for applications to be rebuilt automatically whenever the base is updated, such as when updates are installed or a security vulnerability is discovered.
Taking advantage of this, the approach used during this post will build the application in 2 different phases:
- During the first phase, the SAP Commerce ‘base image’ is built. To do that we are using a Docker Build strategy (dockerStrategy) building the container image by reading the Dockerfile specifications from our source repository. The final result will be an SAP Commerce container image stored in the OpenShift internal registry that can be used later as many times as we need.
- During the second phase, the application and different components will be built and initialized using a ‘Source to Image’ (s2i) strategy where the application source will be merged with the SAP Commerce base image built during the previous phase. As a result, the custom SAP Commerce application container image will be pushed to the internal registry, so this can be used to deploy the application instance later, and reused for different environments and different purposes (Dev, QA, Prod…)
For this post, we’re using OpenShift Container Platform 4.2. To support the build and deploy stages, we are using Nexus and a git server deployed in OpenShift. This procedure can be easily adapted to use any other artifact repository and/or source code management tool. These tools will contain the initial artifacts to build the SAP Commerce base image and the application code that will be deployed on top of that base image. Additionally we are using Secrets and Config Maps that are not part of the templates to store different credentials to login into these systems and allow us to pull in objects.
To support application portability between environments, it is recommended that application configurations be externalized and injected at runtime. This enables the core components of the application (JAR file(s) packaged into an atomic image) to have an independant lifecycle from the configurations. Configurations in SAP Commerce that both override a portion of the default server configuration and support deployed applications are specified within a file called local.properties.
OpenShift supports storing application configurations within the platform in an object called a ConfigMap and sensible data in an object called a Secret. For this use case, we are storing the application configuration that we want to change during runtime in a ConfigMap called ‘hybrisconfig’ and the sensible data in a Secret called ‘hybrislicense’.
Build and deploy process
One of the benefits of the OpenShift Container Platform is that it provides a robust build facility for creating container images. Multiple build strategies are available, giving administrators and developers the flexibility to select an option that best suits their needs.
The process to build the SAP Commerce container base image, the final application container image and the deployment of this application into the platform is fully managed by OpenShift. Templates are used (so they are reusable as many times as needed) to describe how our application is going to be built and deployed, and what objects are created in the platform. The use of ‘everything as code’ (Infrastructure as Code, Configuration as Code…) is a great practice to achieve platform automation, idempotency, reusability and portability.
All the instructions to deploy the required objects are captured in the following GitHub repository. As part of the process we need to download SAP Commerce and extract the ‘hybris’ directory to be used as the base for our SAP Commerce deployment. This is the directory we push to our Artifact Repository to be used during the SAP Commerce base image build process. For the purpose of this post a ‘develop’ environment is set up from the given config templates, but this can be adapted to your specific requirements. This initial “plain” configuration and SAP Commerce platform files, along with the instructions from our Dockerfile will form the final SAP Commerce base image.
For the final application build, the previous created base image is used. This image already has the instructions (the s2i directory previously injected) to build and run the new resultant image from this build process. During the build process the source from our Git server repository is injected in the build container and the instructions from the ‘assemble’ script are executed.
We won’t go deep into the building and customizing process for the SAP Commerce application. The best source for those resources are the SAP Help for SAP Commerce page or SAP Customer Experience Wiki.
Once the final image has been built containing the application, it can be deployed. As part of the used templates, additional objects are created in OpenShift to run the application deployments and manage the internal and external request to the application endpoints. A DeploymentConfig which already has the information of the application container image to be used as well as instructions on how this container image should be deployed is then created.
Once the application has been deployed, they will be accessible via an OpenShift Route that exposes services externally.