IBM Developer

Tutorial

Run container-based workloads on IBM Hyper Protect Virtual Servers for VPC

Use a Docker Compose file to start an OCI container-based workload in a confidential computing environment

By Divya K Konoor, Seenu Suvarna, Anbazhagan Mani, Abhiram Kulkarni, Kalaiarasan Panneerselvam, Sashwat K
Archived content

Archive date: 2025-11-03

This content is no longer being updated or maintained. The content is provided “as is.” Given the rapid evolution of technology, some content, steps, or illustrations may have changed.

IBM Hyper Protect is a feature of IBM zSystems and LinuxONE that provides hardware-level security for virtual servers. It protects Linux® workloads on IBM zSystems and LinuxONE throughout the application lifecycle, from build through to deploy and manage.

In this tutorial, learn how to run a container-based workload on IBM Hyper Protect Virtual Servers for VPC (Hyper Protect Virtual Servers). This tutorial is intended to complement another tutorial, Run container-based workloads on LinuxONE Virtual Servers for VPC. If you previously completed that tutorial, you can reuse some of the same IBM Cloud entities.

Prerequisites

Before completing this tutorial, you should:

Note: The IBM Cloud UI menus can change over time. If you have any questions about the UI or documentation, contact the IBM Hyper Protect Accelerator at: hpa@ibm.com.

Estimated time

It should take you approximately 20 minutes to complete this tutorial.

Steps

For security reasons, you cannot use SSH to access a Hyper Protect Virtual Server instance. This effectively means that you cannot SSH into Hyper Protect Virtual Servers and install Docker and Docker Compose, and start the containers. So, how do you start your container workloads on Hyper Protect Virtual Servers? That's exactly where a Hyper Protect Virtual Servers contract comes in.

The contract is a file that 'we' as users pass in while creating an instance of Hyper Protect Virtual Servers to let it know that there are container workloads that must be brought up when Hyper Protect Virtual Servers start. It's like a short note that you pass on your Hyper Protect Virtual Servers instance to tell it what you need.

It's basically a yaml file where you define information about the container workload you want to start. And what does that mean? It means providing information about your container, such as where it resides. This tutorial uses a simple contract to help you understand what it is. So, let's get started.

In this example, you use an unencrypted contract for simplicity. However, using an encrypted contract is strongly recommended in production environments. More details on how to encrypt a contract can be found in the official documentation.

It is possible to use a Terraform provider to create the contract and proceed with Hyper Protect Virtual Servers instance creation. You can find more information on those steps, which explain how you can create a contract manually and use the IBM Cloud Virtual Private Cloud (VPC) UI to start a Hyper Protect Virtual Servers instance with that contract.

IBM logging instance

Another thing that you need before you proceed with creating a Hyper Protect Virtual Servers instance is an IBM logging instance. If you're wondering why you need a logging instance to proceed with Hyper Protect Virtual Servers creation, it's because as a user you cannot log in to (SSH) the Hyper Protect Virtual Servers instance, and if you want to know what's happening internally, you must have a simple way to view your logs. Therefore, you connect the Hyper Protect Virtual Servers instance to talk to the logging instance so that all logs from the former get routed to the latter. Then, you can use your logging dashboard to view the logs and use it for anything else. So, let’s get started with creating a logging instance.

Create your IBM logging instance

  1. Log in to IBM Cloud, and from the Navigation menu pane, select Observability -> Logging.

    Left panel

  2. Click Options -> Create to create an instance of IBM logging.

    Creating the logging instance

  3. Select the plan you'd like to use, and click Create. In seconds, you have your own ready-to-use instance of IBM logging.

  4. Click Open dashboard from the upper right, then click Open dashboard.

    Opening the dashboard

    The following screen appears.

    Everything screen

  5. Locate and click the Install Instructions (?) icon at the lower left of the icon pane.

  6. Note and copy the Ingestion Key that is displayed in the Overview section on the next page. Click rsyslog from the left pane.

    Selecting ryslog

  7. Copy the endpoint information (highlighted in blue in the image).

    Endpoint information

The two vital pieces of information that you must have to proceed further are:

  1. Ingestion key
  2. Rsyslog endpoint information, which in the previous case is:

    
    syslog-a.jp-tok.logging.cloud.ibm.com:6514
    

What is a Hyper Protect Virtual Servers contract?

A Hyper Protect Virtual Servers contract is a yaml file with multiple sections. As mentioned previously, it is used as an input to the Hyper Protect Virtual Servers instance to tell the instance about what the latter must do while it is starting. The Hyper Protect Virtual Servers service offering is targeted at bringing up OCI container-based workloads in a secure environment. The contract is a way to define the information that the Hyper Protect Virtual Servers instance must have. Take a look at the official documentation and this Hyper Protect technical paper to learn more about the different personas that are associated with the contract and to understand all of the potential contract features that you can try.

To keep it simple, a contract has two mandatory sections:

  • Workload, which is where you provide information about where the container is residing
  • An env section, where you provide information about the IBM logging instance

Why does the contract have multiple sections?

It is assumed that the different pieces of information that are needed to start the workloads on a Hyper Protect Virtual Servers instance comes from different personas. For example, the information about the workload might come from a workload administrator who cares only about building and making the workload available, but the information about the IBM logging instance is an environmental piece of information that comes from the environment admin, who works with IBM Cloud. In short, each section is meant for a different persona and the contract is a consolidation of information from different personas. A contract can have multiple sections. This tutorial discusses two of them.

What is the workload section about?

This section provides information about the containers that you want to start on the Hyper Protect Virtual Servers instance. You can use either a public image or build your own Open Container Initiative (OCI) image and host it in one of the supported container registries. This example uses a public PostgreSQL image as a reference. Learn more about the workload section.

Note: IBM does not provide any container images. Instead, you are expected to "bring your own image."

What is the env section about?

This section provides information about the environment. An example of this is the IBM logging instance. Learn more about the env section.

How do you create the env section in the contract?

Start with the following template for the env section.

   env: |
     type: env
     logging:
       logDNA:
         hostname:<host name of the Log Analysis instance>
           ingestionKey: <ingestion Key of the Log Analysis instance>
           port: <port default-6514>

The previous template, which is populated with values from the IBM logging instance created previously, looks like the following example. Keep this handy, and let's move on to creating the workload section, which is another mandatory section in the contract.

   env: |
     type: env
     logging:
       logDNA:
         hostname: syslog-a.jp-tok.logging.cloud.ibm.com
         ingestionKey: xxxxxxxxxxxxxxxxxxxxxxxxx
         port: 6514

Creating the workload section of the contract

The contract section contains more information about your container. To continue, bring your PostgreSQL docker-compose.yaml file from the previous tutorial. The following code is the Docker Compose file to start a PostgreSQL container.

services:
  postgresql:
    image: docker.io/library/postgres:12@sha256:429c57f9ae8f379601df6df7448b0c2c8df4da23d7ba2cb57fee8da8f262eda0
    ports:
      - "5432:5432"
    environment:
      - POSTGRES_HOST_AUTH_METHOD=trust

Now, you must follow a few steps to get this going for Hyper Protect Virtual Servers. You basically must compress the file and perform Base64 encoding on it, as seen in the following code. Note that these are mandatory steps.

# tar czvf compose.tgz docker-compose.yaml
docker-compose.yaml
# base64 -w0 compose.tgz > compose.b64
# cat compose.b64
H4sIAAAAAAAAA0rJT85OLdJNzs8tyC9O1atMzM1hoDYwAAIzExMwDQTotIGJgRmDoYmpkZGJkaGxuRmDgaGxsZkBg4IBFd2AE5QWlyQWKSgwFOXnl+BRRkh+qILi1KKyzOTUYisuBYWC/OKS9KLU4sIcEE9BITM3MT3VSgGSRPQy8/VzMpOKEosq9WEKrQyNHIozEo1MzaxMjCyTTc3TLBNTLdKMzS3NDAxT0sxS0sxNTCySDJKNki1S0kxSEo2MU8yTEo2Sk4BKU1MtUhIt0ozMjFJTEg3AFhbkF5UUQ+xWUNBVUDI1MTayAhFKYLHUvLLMovy83NS8EoSiAP/gEPcg1+B4DyAj3jE0xCPe1zXEw9/FtqQIGLcKCpgqAxyDg8P9g1xsCxKLi8sNilK4hl+8jnQw0sFIByMdjHQw0sFIByMdjHQw0sFIByMdEAsA7P1ddxtHtq356/39/f39/f39/f39/f39le/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/vXPzl+/v7e0YEdNBBBx100EEHHXTQQQcddNBBBx100EEHHXTQQQddWwAAAP//3bpIGgAoAAA=

Now, let's use the previous Base64-encoded content to create the workload section of the contract, as seen in the following code.

workload: |
  type: workload
  compose:
    archive: H4sIAAAAAAAAA0rJT85OLdJNzs8tyC9O1atMzM1hoDYwAAIzExMwDQTotIGJgRmDoYmpkZGJkaGxuRmDgaGxsZkBg4IBFd2AE5QWlyQWKSgwFOXnl+BRRkh+qILi1KKyzOTUYisuBYWC/OKS9KLU4sIcEE9BITM3MT3VSgGSRPQy8/VzMpOKEosq9WEKrQyNHIozEo1MzaxMjCyTTc3TLBNTLdKMzS3NDAxT0sxS0sxNTCySDJKNki1S0kxSEo2MU8yTEo2Sk4BKU1MtUhIt0ozMjFJTEg3AFhbkF5UUQ+xWUNBVUDI1MTayAhFKYLHUvLLMovy83NS8EoSiAP/gEPcg1+B4DyAj3jE0xCPe1zXEw9/FtqQIGLcKCpgqAxyDg8P9g1xsCxKLi8sNilK4hl+8jnQw0sFIByMdjHQw0sFIByMdjHQw0sFIByMdEAsA7P1ddxtHtq356/39/f39/f39/f39/f39le/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/vXPzl+/v7e0YEdNBBBx100EEHHXTQQQcddNBBBx100EEHHXTQQQddWwAAAP//3bpIGgAoAAA=

Create the full contract with all sections

Now that you've created both the env and workload sections of the contract, it should look similar to the following code. You can put it into a file for future reference.

env: |
  type: env
  logging:
    logDNA:
      hostname: syslog-a.jp-tok.logging.cloud.ibm.com
      ingestionKey: xxxxxxxxxxxxxxxxxxxxxxxxxxx
      port: 6514
workload: |
  type: workload
  compose:
    archive: H4sIAAAAAAAAA0rJT85OLdJNzs8tyC9O1atMzM1hoDYwAAIzExMwDQTotIGJgRmDoYmpkZGJkaGxuRmDgaGxsZkBg4IBFd2AE5QWlyQWKSgwFOXnl+BRRkh+qILi1KKyzOTUYisuBYWC/OKS9KLU4sIcEE9BITM3MT3VSgGSRPQy8/VzMpOKEosq9WEKrQyNHIozEo1MzaxMjCyTTc3TLBNTLdKMzS3NDAxT0sxS0sxNTCySDJKNki1S0kxSEo2MU8yTEo2Sk4BKU1MtUhIt0ozMjFJTEg3AFhbkF5UUQ+xWUNBVUDI1MTayAhFKYLHUvLLMovy83NS8EoSiAP/gEPcg1+B4DyAj3jE0xCPe1zXEw9/FtqQIGLcKCpgqAxyDg8P9g1xsCxKLi8sNilK4hl+8jnQw0sFIByMdjHQw0sFIByMdjHQw0sFIByMdEAsA7P1ddxtHtq356/39/f39/f39/f39/f39le/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/vXPzl+/v7e0YEdNBBBx100EEHHXTQQQcddNBBBx100EEHHXTQQQddWwAAAP//3bpIGgAoAAA=

Where are you going to use this contract?

The contract is passed in as input while creating the Hyper Protect Virtual Servers instance in IBM Cloud. This is passed in within the 'user-data' section of the Create Virtual Server Instance page. When the Hyper Protect Virtual Servers instance starts, it validates the contract to check whether all of the needed sections are present. As the next step, it extracts information from the env section to check whether the IBM logging endpoint is reachable and configures the Hyper Protect Virtual Servers logs to be routed to the same location. Subsequently, it extracts information from the workload section to pull the container images from the registry and brings up the workload.

Start PostGreSQL with Hyper Protect Virtual Servers for VPC

Now, use the previously created contract to start the PostgreSQL workload on an instance of Hyper Protect Virtual Servers for VPC. Keep in mind that it's the same workload that you brought up on the LinuxONE zVSI instance.

How to create a Hyper Protect Virtual Servers instance

  1. Log in to IBM Cloud. As before, click VPC Infrastructure -> Virtual Machines, and click Create from the upper right. After the Create page opens, select the Region of your choice.

    Selecting location

  2. Name the Hyper Protect Virtual Servers instance.

    Naming the instance

Hyper Protect image and profile

  1. Click Change Image from the Image and profile section, and select IBM Z, LinuxONE architecture.

    Note: It's important that you enable the Confidential Computing toggle button. If you don't enable the toggle button, you cannot view the ibm-hyper-protect-container-runtime images that you need.

    Selecting an image

  2. Select the image, and click Save.

  3. Select the instance profile by clicking Change Profile and selecting the instance profile of your choice. Ensure that the processor type selected is IBM Z and that Confidential Computing is also selected, as shown in the following image.

    Selecting image profile

    Image and profile

You don't have to provide an SSH key because the Hyper Protect Virtual Servers instance is non-SSHable. You can leave it empty. Even if you pass in a key, it is ignored.

SSH keys

Additional storage

In this example, you rely on the storage that is provided as part of the image and do not use any additional disks or volumes. However, it's important to note that Hyper Protect Virtual Servers supports encrypted data disks to securely store workload data. However, this feature is not explained in this tutorial. It will be covered in a future tutorial.

Storage

VPC and subnets

As before with LinuxONE zVSI, for networking, you must ensure that you have a VPC and corresponding subnet.

Subnet

User data and contract

Now comes the important part that you do not want to miss, user data, which is the section that is used to communicate with your Hyper Protect Virtual Servers instance. If you've been wondering how you were going to use the contract you created, it's time to put it to use. Here's how you do it.

  1. Copy the contents of your contract (basically, the env and workload sections), and put it into the user-data section under Advanced Options, as seen in the following image.

    Advanced options

  2. Click Create Virtual Server.

  3. Reserve a floating IP and bind it to the Hyper Protect Virtual Servers instance that is starting.

    When you click Create Virtual Server, you want to reserve a floating IP and bind it to the Hyper Protect Virtual Servers instance that is starting. Why should you do that? Because without the floating IP, the Hyper Protect Virtual Servers instance cannot communicate with the IBM logging instance. If it's not able to communicate with the logging instance, it assumes that there’s not a logging instance and shuts itself down. So, you must ensure that you have bound the floating IP to the Hyper Protect Virtual Servers instance when it starts to boot.

    What happens if you forget to bind the floating IP? Go ahead and bind the IP, and then restart your Hyper Protect Virtual Servers instance. When you restart it, it attempts to connect to the logging instance again, and this time it should go through.

    Floating IP

    Note: If you do not want to expose your Hyper Protect Virtual Servers instance with a public floating IP, you also have the option of creating a public gateway and using that instead of a floating IP. More details on the creation of a public gateway can be found in the IBM Cloud documentation.

    Virtual server instances

While your Hyper Protect Virtual Servers for VPC instance is starting, you can open the serial console and look at the log messages. You should see something that says "Logging has been configured" and "VSI has started successfully", as shown in the following image.

Logging console

If you are seeing the previous messages, it means that things are progressing well. Your Hyper Protect PostgreSQL instance is up and running.

PostgreSQL instance running

Access PostgreSQL externally

As you did previously, you want to open the port for external access. You can either create a new security group or use the existing one. This example uses the existing one. Note that in the following example, only ports for inbound traffic have been opened, not for outbound traffic. So, that’s something that you want to add rules for. The following rule is just a sample. Find more details on using IBM Cloud VPC Security Groups in the IBM Cloud documentation.

postgres image

Edit inbound rule

Ensure that the security group is added to your Hyper Protect Virtual Servers instance. Navigate to the Virtual Servers page, select your Hyper Protect Virtual Servers instance, and add the security group.

Edit network interface

Network interface

Now, use your laptop or any other server to access this PostgreSQL workload externally through the public IP (floating IP) and port.

psql -h <floating ip>  -p 5432 -U postgres

Accessing the PostgreSQL workload

Your first Hyper Protect Virtual Servers instance running PostgreSQL workload is now up and running, and is accessible externally.

Access Hyper Protect Virtual Servers logs through IBM logging

Additionally, you can go to your IBM logging instance to see whether the logs from within the Hyper Protect Virtual Servers instance are getting routed to your logging instance correctly. Go back to the Logging page, and click Open Dashboard.

Logging dashboard

You can find all of the logs from within your Hyper Protect Virtual Servers instance that is routed to your logging instance. The same IBM logging instance can be used with multiple Hyper Protect Virtual Servers instances.

Logging instances

Summary and next steps

In this tutorial, you learned how you can use the same Docker Compose file that you used previously with the LinuxONE zVSI instance to start an OCI container-based workload in a confidential computing environment using IBM Hyper Protect Virtual Server. Hyper Protect Virtual Servers for VPC has many more security features that were not discussed in this tutorial. The next tutorial in this series will explore more of these features.