tc Server Kubernetes How-to

Note: VMware tc Server does not distribute docker images. There are steps on how to create your own docker image. An image containing your webapp and tc Server may be build using the tc Server Cloud Native Buildpack.

Note: This document assumes you have access to a Kubernetes cluster. VMware Enterprise PKS may be used or any other Kubernetes platform. The instructions for setting up a cluster are beyond the scope of this document. The kubectl commands provided in this document assume you are already connected to the intended cluster.

Features have been added to VMware tc Server version 4.1.0 which make it simple to use VMware tc Server with Kubernetes. This is a guide provides instructions on how to utilize these new features.

Getting Started

In order to get started with using you will need a release of VMware tc Server 4.1. Be sure to download 4.1.0 or newer. A kubernetes cluster is also required. This may be VMware Enterprise PKS or any variant of kubernetes. Setting up the cluster is beyond the scope of this document.

Creating a Docker Image

The following is an example of a Dockerfile which will build a kubernetes ready VMware tc Server docker image.

Download pivotal-tc-server-4.1.0-RELEASE.deb and pivotal-tc-runtime-9.0.31.B-RELEASE.deb from VMware tc Server 4.1 Core and VMware tc Server 4.1 Runtimes then place them and the following Dockerfile in the same directory.

FROM 'bellsoft/liberica-openjdk-debian:11'

RUN touch /instance-descriptor.yaml

COPY pivotal-tc-server-4.1.0-RELEASE.deb /tmp
COPY pivotal-tc-runtime-9.0.31.B-RELEASE.deb /tmp

RUN dpkg -i /tmp/pivotal-tc-server-4.1.0-RELEASE.deb /tmp/pivotal-tc-runtime-9.0.31.B-RELEASE.deb

ENV TCSERVER_HOME=/opt/pivotal/tcserver/standard
ENV JAVA_HOME=/opt/java/openjdk


CMD $TCSERVER_HOME/tcserver create-from-file /instance-descriptor.yaml --run

Then run the following command:

docker build --tag vmware-pivotal-tcserver-standard:4.1.0 .

In a production environment the above steps can be performed via a continuous build service which polls VMware Tanzu Network for updated images. The instructions for this are beyond the scope of this document.

This is a generic docker image containing VMware tc Server which can be used to create a tc Runtime instance and run your web application. The Dockerfile above utilizes a new in 4.1.0 feature of VMware tc Server which will run in the foreground an instance after it is created.

Note: The VMware EULA does not allow republishing of VMware tc Server please do not publish VMware tc Server images to public registries.

Using Configmap and Secrets

The image created above does not contain a populated instance descriptor file. This means that each container will need a valid instance descriptor mapped to it. An example of a basic instance descriptor file follows:

  name: tomcat-sample-app

The above example utilizes a new feature of VMware tc Server 4.1.0 which will deploy a .war file during the creation of the instance. In this case it deploys the ASF Tomcat sample application to the ROOT (“/”) context. Copy and save the above example as tcserver-tomcat-sample-app-instance.yaml

Create the configmap for the above example:

kubectl create configmap tcserver-tomcat-sample-app-instance --from-file=tcserver-tomcat-sample-app-instance.yaml

Check to make sure everything looks correct and run the following command

kubectl describe configmap tcserver-tomcat-sample-app-instance

Which should show you output similar to the following:

Define the sample pod, save as tcserver-tomcat-sample-app-instance-pod.yaml

apiVersion: v1
kind: Pod
  name: tcserver-tomcat-sample-app-instance
  - name: vmware-pivotal-tcserver-standard-4-1-0
    image: <pointer to your image>
     - name: config-volume
       mountPath: /instance-descriptor.yaml
       subPath: tcserver-tomcat-sample-app-instance.yaml
  - name: regcred
    - name: config-volume
        name: tcserver-tomcat-sample-app-instance
  restartPolicy: Never

You will need to replace <pointer to your image> with the location of your docker image and regcred with the secret containing the authentication for your registry. Save this as tcserver-tomcat-sample-app-instance-pod.yaml

To create the regcred secret you can use something similar to the following:

kubectl create secret docker-registry regcred --docker-server="<docker server>" --docker-username="<docker username>" --docker-password="<docker password>" --docker-email="<docker email>"

Replace the <variables> with their actual values for your docker registry.

Note: The VMware EULA does not allow republishing of VMware tc Server please do not publish VMware tc Server images to public registries.

Create the pod

kubectl apply -f tcserver-tomcat-sample-app-instance-pod.yaml

If all goes well you should see the message pod/tcserver-tomcat-sample-app-instance created

Check to make sure the pod has started. The first time the docker image is downloaded could take a few moments. The following command can be used to check the status.

kubectl describe pod tcserver-tomcat-sample-app-instance

The last two lines should look similar to the following:

  Normal  Created    21s   kubelet, 4b4b2a48-4ca6-494d-b297-20bb0f4996d1  Created container
  Normal  Started    21s   kubelet, 4b4b2a48-4ca6-494d-b297-20bb0f4996d1  Started container

The Started container message should indicate success. If there are messages about failure because of issues downloading the image please check the references to the docker image and credentials.

Check the logs

kubectl logs tcserver-tomcat-sample-app-instance

The output should be the same as you would see from successfully creating an instance and running it.

Verify the instance deployed the Tomcat sample application. The following will redirect port 8080 on the pod to your local 8080.

kubectl port-forward  tcserver-tomcat-sample-app-instance 8080:8080

From another terminal run

curl http://localhost:808

or visit http://localhost:8080 in your browser.

Using Secrets with Properties File

VMware tc Server has features which allows it to resolve environment variables which enables it to use kubernetes secrets.

Secrets in

VMware tc Server will attempt to resolve a property value via an environment variable if not found as an existing property in there are some rules for this behavior which will be outlined below.

As an example, if the db.password property in has a value of $DB_PASSWORD, then VMware tc Server will look for an environment variable named DB_PASSWORD and use that value for db.password.

Rules for Environment Variables

  • Will always attempt to resolve as a key name in first before looking in the environment.
  • Periods (.) in a property name will be replaced with an underscore (_) prior to looking in the environment.
  • All property names are converted to uppercase prior to looking in the environment.


In the following snippet the value of password has been set to ${db.password} which will be searched for in conf/ as the property key db.password if the key doesn’t exist, then the environment variable DB_PASSWORD will be looked at and if found the value of DB_PASSWORD will be used as the value of the password attribute.

<Resource name="jdbc/myoracle" auth="Container"
              type="javax.sql.DataSource" driverClassName="oracle.jdbc.OracleDriver"
              username="appuser" password="${db.password}" maxActive="20" maxIdle="10"

It is also possible to use an environment variable directly as a value for a property in


The above will instruct the property resolver to look for a property named DB_PASSWORD in and if found that value will be used. If that value is not found, then an environment variable named DB_PASSWORD will be looked at and if found the value will be used.

Creating instance’s with Environment Variables as property values

If you want to create variable nio.http.port values and know this when creating the instance. Then specifying an empty value for the property will cause the VMware tc Server tc Runtime instance will look for NIO_HTTP_PORT environment variable.

tcserver create demo-variable -p nio.http.port=

The above command will create an empty value for the nio.http.port property in and the Connector Summary will show an empty port value such as:

Connector summary
  Port:    Type: Non-Blocking IO   Secure: false

When the instance is started the nio.http.port property name will be matched against the environment variable NIO_HTTP_PORT and that value will be used.