WebSphere Application Server & Liberty

 View Only

Lessons from the field #9: Liberty in Containers Part 2

By Brent Daniel posted Wed September 29, 2021 10:02 AM

In the previous "Lessons from the field" post we covered performance optimizations for Java running in containers. Joe McClure added some additional Liberty container performance optimizations in his blog post here. In this post, we will cover some more general tips on using Liberty in containers. 

Obtaining Liberty Container Images

Liberty container images are available from both Docker Hub and the IBM container registry. Both Open Liberty and WebSphere Liberty are available using both Ubuntu and the Red Hat Universal Base Image (UBI). You can further customize the image using the image tag. The available options are:

Version - You can specify a version number such as, or leave it out to select the latest fix pack

Feature Set - Specifying 'full' will give you an image with all available features installed. Specifying 'kernel-slim' (for Open Liberty) or 'kernel' (for WebSphere Liberty) will give you an
image without any features installed. For more information on the tradeoffs involved in using the kernel image, see Joe's previous blog post.

Java version - On Open Liberty you can use 'java8', 'java11', or 'java15' to choose a Java version. With WebSphere Liberty you can choose 'java8' or 'java11'

Java vendor - You can choose either 'openj9' or 'ibmjava'

Architecture - WebSphere Liberty images support additional architectures. You can choose 's390x', 'ppc64le', or 'amd64'

For example, to pull Open Liberty version using version 8 of OpenJ9 java that contains all features from DockerHub, you would run:

docker pull openliberty/open-liberty:

IBM Container Registry Images

Open Liberty and WebSphere Liberty images on both Ubuntu an UBI can be accessed on the IBM container registry using icr.io/ibm/liberty:<tag>. For example,
icr.io/ibm/liberty: would be used to pull version of the WebSphere Liberty kernel image with version 8 of OpenJ9.
icr.io/ibm/liberty: would be used to pull version of the Open Liberty 'full' image with version 11 of OpenJ9.

For more information on Liberty in the IBM container registry and a list of available images, see the IBM Cloud container registry documentation here.

Source To Image (S2I) Liberty Images

An alternative to using the above images would be to use the Open Liberty or WebSphere Liberty "Source To Image" (S2I) images. With S2I, you would reference a Liberty S2I repository and a source code repository that contains your application code to automatically construct a container image. For example, the following commands would construct and run a WebSphere Liberty container named websphere-liberty-test that contains a sample application named 'ferret':

$ s2i build https://github.com/WASdev/sample.ferret.git ibmcom/websphere-liberty-s2i: websphere-liberty-test
$ docker run -p 9080:9080 websphere-liberty-test

The S2I utility will build the application in the github repository using Maven, and create a new container image with the application binaries installed. 

Open Liberty S2I images are available on docker hub using openliberty/open-liberty-s2i:{version}-{java version}, where the java version can be either java8 or java11. Similarly, WebSphere Liberty S2I images are available using ibmcom/websphere-liberty-s2i:{version}-{java version}. For more information, see the github repositories for Open Liberty S2I and WebSphere Liberty S2I

Configuring Liberty Containers

You can configure your Liberty containers manually by copying in a server.xml file during the container build process:
COPY --chown=1001:0 server.xml /config/

Applications can be copied to the 'apps' or 'dropins' directories:
COPY --chown=1001:0 Sample1.war /config/dropins/
COPY --chown=1001:0 Sample2.war /config/apps/

If you are using the 'kernel-slim' Open Liberty image, ensure that you are running the 'features.sh' script as part of the build to install required features:

RUN features.sh

Liberty features are downloaded from maven central by default, but you can change the repository used by the features.sh script by adding a file named featureUtility.properties:

COPY --chown=1001:0 featureUtility.properties /opt/ol/wlp/etc/

For more information on the featureUtility.properties file, see the documentation here

Logging in JSON format

In a containerized environment, you may want to consider logging in JSON format for consumption by an external logging stack such as the elastic stack.

You can configure logging in JSON format in bootstrap.properties, or through environment variables set either at build time or during container invocation.

To enable JSON logging using bootstrap.properties, add the following to your bootstrap.properties file:


Copy the bootstrap.properties file into Liberty's configuration directory by adding the following to your Dockerfile:

COPY --chown=1001:0 bootstrap.properties /config/

To enable logging of all sources in JSON format at build time using environment variables, add the following to your Dockerfile:

ENV WLP_LOGGING_CONSOLE_SOURCE=message,trace,accessLog,ffdc,audit

To enable the same variables at runtime, they would be passed into the Docker command using `-e`:

docker run -d -p 80:9080 -p 443:9443 -e WLP_LOGGING_CONSOLE_FORMAT=JSON -e WLP_LOGGING_CONSOLE_LOGLEVEL=info -e WLP_LOGGING_CONSOLE_SOURCE=message,trace,accessLog,ffdc,audit websphere-liberty:latest

Directory Structure

The directory /liberty is a symbolic link to /opt/ibm on WebSphere Liberty images, and /opt/ol on Open Liberty images.

Liberty on Docker changes the directory of messages.log and FFDC to /logs using the LOG_DIR environment variable.

Liberty on Docker changes the current working directory of the Liberty process to /liberty/wlp/output using the WLP_OUTPUT_DIR environment
variable. This directory will contain any javacores or other dump files generated during the runtime of the container.

The symbolic link /config will point to the /liberty/wlp/usr/severs/defaultServer directory. This directory will contain files such as:
/config/server.xml - The primary configuration file for the server
/config/bootstrap.properties - Contains properties to be set before the server begins starting
/config/server.env - Contains variables that will be set in the environment prior to starting the server
/config/configDropins/defaults - Contains configuration files that will not take precedence over conflicting configurations in server.xml
/config/configDropins/overrides - Contains configuration files that will take precedence over conflicting configurations in server.xml
/config/dropins - Contains applications that are not defined in server.xml
/config/apps - The default directory for applications that are defined in server.xml

In a non-container environment, JVM parameters are typically provided in the jvm.options file. This file does not support variable substitution, so in a container environment these parameters should be specified either by using the JVM_ARGS environment variable or by mounting the jvm.options file.

More Information

The Open Liberty Guides site has several resources for learning how to use Liberty in containers, such as Containerizing Microservices and Containerizing, Packaging, and Running a Spring Boot application

In a future blog post, we will cover running Liberty containers in a Kubernetes environment.