Deploying a PostgreSQL DB on IBM Hyper Protect Virtual Server for VPC
*CTO’s Notes: Building on our previous experiences, this article discusses our evolved strategy for deploying a PostgreSQL database on IBM Hyper Protect Virtual Servers. We transitioned to a more sophisticated approach, utilizing Docker for database deployment – a method that not only streamlined the process but also enhanced security and scalability. Here, we share the intricate details of this deployment method and the significant advantages it offers.
Today, we would like to walk you through the journey of building your PostgreSQL DB docker container image in an IBM Z Virtual server instance(zVSI) on IBM Cloud and then deploying the image in a contract as an IBM Hyper Protect Virtual Server instance.
There are 6 steps in this journey:
Step 1: Launch an IBM Z Virtual server instance(zVSI) on IBM Cloud
Step 2: SSH into your zVSI and create your docker-compose and Dockerfile for your PostgreSQL DB
Step 3: Test your docker container image by running docker-compose up
in your zVSI to ensure it runs well in s390x architecture
Step 4: Build your container image for s390x architecture and push it into IBM Container Registry
Step 5: Create the contract using Terraform
Step 6: Initialize your IBM Hyper Protect Virtual Server instance with the contract from Step 5
Before you begin,
You need to meet the following prerequisites:
- Create an IBM Cloud account.
- Create an API key for your user identity.
- Install IBM Cloud CLI and the container registry CLI plug-in.
- Install Git, Terraform, OpenSSL, PostgreSQL, Docker and Docker buildx
- Create a VPC and a subnet with a public gateway and a security group with rules that allow at least inbound IP connections on port 5432 and all outbound IP connections.
- Create a Log Analysis instance on IBM Cloud. Make a note of the ingestion host and the ingestion key.
Step 1: Launch an IBM Z Virtual server instance(zVSI) on IBM Cloud
Go to the IBM Cloud catalog and select "Virtual Server for VPC"
Choose your preferred location. For example, if you are in Singapore, select "Asia Pacific," and then choose the "Tokyo" region.
Give your instance a name.
Select your preferred image. Under the Architecture section, ensure that you select the s390x architecture "IBM Z, LinuxONE".
Next, select your profile.
Choose an SSH key to use for accessing the instance. If you don't have an SSH key, you can follow the instructions to generate one.
Optionally, add data volumes on top of the boot volume.
Configure your VPC (Virtual Private Cloud) and request a floating IP address for your instance.
Click the "Create virtual server" button. Your new virtual server will be provisioned and available for use shortly.
After your virtual server has been provisioned, assign a floating IP address to the new virtual server instance and click Save because you will need to SSH in the next step.
Step 2: SSH into your zVSI and create your docker-compose and Dockerfile for your PostgreSQL DB
Once your instance is provisioned, you can access it by SSH using the floating IP address and the SSH key you selected during the setup earlier.
ssh -i your-ssh-key.pem root@floating-ip-address
Create a new working directory
COPYCOPY
mkdir postgres-db
Cd to the new working directory
COPYCOPY
cd postgres-db
Create your Dockerfile
COPYCOPY
# Use the official PostgreSQL image from Docker Hub
FROM postgres:latest
# Environment variables
ENV POSTGRES_DB=<postgres_db>
ENV POSTGRES_USER=<postgres_user>
ENV POSTGRES_PASSWORD=<postgres_user_password>
# Expose the default PostgreSQL port
EXPOSE 5432
where
<postgres_db>
is the name of your database
<postgres_user>
is the username which you will be using to access the database
<postgres_user_password>
is the password of the username which you will be using to access the database
Create your docker-compose.file
COPYCOPY
version: '3'
services:
postgres:
image: postgres:14-alpine
ports:
- 5432:5432
volumes:
- ~/apps/postgres:/var/lib/postgresql/data
environment:
- POSTGRES_PASSWORD=<postgres_user_password>
- POSTGRES_USER=<postgres_user>
- POSTGRES_DB=<postgres_db>
Step 3: Test your docker container image by running docker-compose up
in your zVSI to ensure it runs well in s390x architecture
In the same working directory which contains your Dockerfile and docker-compose.yml, run the command:
COPYCOPY
docker-compose up
Verify that the docker-compose up
command is run successfully by running the docker ps -a
command:
COPYCOPY
$ docker ps -a
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
94d146cce7bb postgres:14-alpine "docker-entrypoint.s…" 37 minutes ago Up 36 minutes 0.0.0.0:5432->5432/tcp, :::5432->5432/tcp postgres-db_postgres_1
It is important to ensure that your docker container is running well in your zVSI on s390x architecture. Similarly, you may try to connect to your Postgres DB using the command:
COPYCOPY
$ psql -h localhost -U <postgres_user> -d <postgres_db> -p 5432
Password for user spiking_user: <postgres_user_password>
where
<postgres_db>
is the name of your database
<postgres_user>
is the username
<postgres_user_password>
is the password of the username
which you have created in the Dockerfile and docker-compose.yml previously
Step 4: Build your container image for s390x architecture and push it into IBM Container Registry
Now that we have ensured that our docker container is working well in zVSI on s390x architecture, we are ready to push the container image into the IBM Container Registry.
In the same working directory which contains your Dockerfile and docker-compose.yml, build the container image for the s390x architecture and tag the container image with the following command:
COPYCOPY
docker buildx build --platform linux/s390x -t jp.icr.io/hpvs-spiking/postgres-db .
where
jp.icr.io
is the region of your IBM container registry
hpvs-spiking
is a namespace in your IBM container registry
postgres-db
is your application name
Log in to the IBM Cloud Container Registry with the following commands:
COPYCOPY
$ ibmcloud login -u iamapikey --apikey <your API Key>
API endpoint: https://cloud.ibm.com
Region: jp-tok
Authenticating...
OK
where
<your API Key>
is the API Key of the IAM user you have created in your IBM cloud account
I have selected Japan-Tokyo as the region of my IBM container registry
You may use the command below to switch to another region e.g. us-south:
COPYCOPY
ibmcloud target -r us-south
Lastly, run the command:
COPYCOPY
ibmcloud cr login --client docker
Create a namespace and push the container image by running the following commands:
COPYCOPY
ibmcloud cr namespace-add hpvs-spiking
where
hpvs-spiking
is a namespace in your IBM container registry
Push the container image you created earlier by using the command:
COPYCOPY
docker push jp.icr.io/hpvs-spiking/postgres-db
Display the container image digest. You can view and note the container image digest in your container registry, or alternatively use the following command:
COPYCOPY
docker inspect jp.icr.io/hpvs-spiking/postgres-db | grep -A 1 RepoDigests
Step 5: Create the contract using Terraform
To provision the IBM Hyper Protect Virtual Server instance in the next step, you would need to first create a contract. You may create a contract manually or use Terraform which aids in reducing the time needed for contract creation.
Follow the steps below to use Terraform to create a contract:
Use Git to clone the repo
Move to the following directory with the command:
COPYCOPY
cd linuxone-vsi-automation-samples\terraform-hpvs\create-contract-dynamic-registry
Update the docker-compose.yml file in the compose folder. You need to specify your container image digest and the exposed ports. See the following example of a docker-compose.yml file:
COPYCOPY
version: "3"
services:
tradegpt:
image: ${REGISTRY}/hpvs-spiking/postgres-db@sha256:<sha256>
ports:
- "5432:5432"
where
<sha256>
is the image digest in your container registry
Set the required Terraform variables. To do so, you need to copy the file my-settings.auto
.tfvars-template
to my-settings.auto
.tfvars
, edit the copied file, and adapt the variable values. See the following example:
COPYCOPY
registry="jp.icr.io"
pull_username="iamapikey"
pull_password="<your API key>"
logdna_ingestion_key="<the ingestion key of your log instance>"
logdna_ingestion_hostname="syslog-a.jp-tok.logging.cloud.ibm.com"
where
jp.icr.io
is the region of your IBM container registry
jp-tok
is the region of your logging instance
<your API Key>
is the API Key of the IAM user you have created in your IBM cloud account
<the ingestion key of your log instance>
which you can retrieve on IBM cloud for your respective logging instance
To initialize Terraform, run the following command:
COPYCOPY
terraform init
Create the contract by using Terraform:
COPYCOPY
terraform apply
Display the contract that is created with the Terraform script by running the following command:
COPYCOPY
cat build/contract.yml
💡Copy the displayed contract. You need to paste the copied contract into the User Data text field in the next step.
Step 6: Initialize your IBM Hyper Protect Virtual Server instance with the contract from Step 5
- Log in to IBM Cloud.
- Go to the provisioning page for IBM Hyper Protect Virtual Server for VPC on the IBM Cloud catalog.
3. Name the virtual server instance
4. Ensure that the image is an IBM Hyper Protect image running on s390x Architecture
5. Paste the created contract information into User data.
6. Under the Networking, select your VPC and subnet.
7. Click Create Virtual Server.
8. Assign a floating IP address to the IBM Hyper Protect Virtual Server Instance and click Save.
9. Under your security group, ensure that you allow at least inbound IP connections on port 5432 and all outbound IP connections so that in the very last step, you will be able to connect to your PostgreSQL DB via <floating-ip-address>
and the default PostgreSQL port of 5432
10. View the logs in the Log Analysis instance dashboard.
11. Ensure that there's no error in the logs and that the IBM Hyper Protect Virtual Server is started successfully
12. Copy and paste the <floating-ip-address>
and you may connect to your Postgres DB on the IBM Hyper Protect Virtual Server instance using the command:
$ psql -h <floating-ip-address> -U <postgres_user> -d <postgres_db> -p 5432
Password for user spiking_user: <postgres_user_password>
Continue to our subsequent article to explore how we applied these improved deployment strategies to launch a React Web Application on IBM Hyper Protect Virtual Servers.