Deploying PostgreSQL JDBC driver to Docker/Kubernetes WSO2 API Manager

Currently, the WSO2 Product Docker images available in the Docker registry are prepackaged with the following artifacts,

  1. MySQL Connector / J (MySQL JDBC Driver).
  • Currently, all container based deployments of WSO2 products
    (ex: Resources for Docker Compose Or Container orchestration platforms such as, Kubernetes) use MySQL as the default RDBMS.
  • Hence, WSO2 product Docker images are shipped with the MySQL Connector / J prepackaged, to avoid the hassle of requiring to include the MySQL JDBC driver during a quick start deployment.

2. WSO2 Kubernetes membership scheme artifacts.

  • WSO2 products (Carbon version 4 based) use WSO2 Kubernetes membership scheme for member discovery during product clustering in Kubernetes based WSO2 product deployments.
  • WSO2 Kubernetes membership scheme Java Jar file
    ( kubernetes-membership-scheme-xxxjar ) and DNS Java Jar file,
    a dependency of the Kubernetes membership scheme implementation
    ( dnsjava-xxxjar ) are prepackaged with every WSO2 Carbon version 4 based product Docker image.

Any other artifacts other than the one’s that are prepackaged including the
( postgresql-<version>.jar ) should be manually deployed to the Product.

There are few ways we can deploy the PostgreSQL JDBC driver to the Docker WSO2 API Manager 3.1.0,

  • Direct volume mount introducing the driver.
  • Indirect volume mount introducing the driver.
  • Prepackage the driver in a customised docker image using a Dockerfile.

We can use this option if we have limited number of artifacts to be deployed to the docker container.

Follow the steps below to deploy the PostgreSQL JDBC Driver to the Docker container using a direct volume mount.

  • Place the PostgreSQL driver into the folder anywhere in the host machine where the docker is running, for example,
    <ARTIFACTS>/postgresql-<version>.jar , where <ARTIFACTS> stands for the absolute file system path to the directory in which the JAR file is placed in the Docker host.
  • Grant read permission to other users for,
    <ARTIFACTS>/postgresql-<version>.jar file,
chmod o + r <ARTIFACTS>/postgresql-<version>.jar
  • Run the Docker container instance using docker.wso2.com/wso2am:3.1.0 docker image
    (WUM updated API Manager 3.1.0 base docker image) with the artifact mounted as a volume mount to the container from the Docker host.
docker run 
-v <ARTIFACTS>/postgresql-<version>.jar:/home/wso2carbon/wso2am-2.6.0/repository/components/lib/postgresql-<version>.jar
-it --rm -p 9443: 9443 docker.wso2.com/wso2am:3.1.0

-v options is used to specify the volume mount.

Here, we have used a direct volume mount from the Docker host to the original location of the WSO2 product home in the container to deploy the PostgreSQL JDBC driver.

This is similar to the direct volume mount, but the only difference is instead of mounting individual files we are going to mount a directory from the Docker host system to the container.

Using this approach we can deploy any number of artifacts using the exact folder structure as in the original WSO2 product pack in the mounted directory(eg: <ARTIFACTS>).

In this approach we are going to use a single Docker volume mount with multiple artifacts. To achieve this goal using a single Docker volume mount, any WSO2 product Docker image provides an optional volume mount location at /home/wso2carbon/wso2-artifact-volume.

We are going to mount the <ARTIFACTS> directory to the /home/wso2carbon/wso2-artifact-volume volume mount location as below,

docker run -v <ARTIFACTS>:/home/wso2carbon/wso2-artifact-volume -it --rm -p 9443: 9443 docker.wso2.com/wso2am:3.1.0

For this approach to correctly mount the artifacts inside the <ARTIFACTS> directory to the volume mount, the artifacts within the mounted folder <ARTIFACTS> should maintain the same folder structure as in the original WSO2 product pack.

For example,
Since, PostgreSQL JDBC connector is intended to be placed in the
<WSO2_APIM_HOME>/repository/components/lib/ directory,
the jar file should be placed in
<ARTIFACTS>/repository/components/lib/postgresql-<version>. jar.

Folder structure will look like the below,

<ARTIFACTS>
| -> repository
| -> components
| -> lib
| -> postgresql-<version>.jar

Since this volume mount location lies outside of the WSO2 product home in the container, this option involves an indirect volume mount in deploying the PostgreSQL JDBC driver.

This option is useful if the deployment is managed by container orchestration softwares like Kubernetes.

In Kubernetes introducing artifact jar files using direct or indirect volume mount is not supported, we can only mount configuration files (using configMaps).

So the viable option is to create a Dockerfile to add the PostgreSQL JDBC Driver and build a custom docker image on top of the base API Manager 3.1.0 docker image.

There are two main steps involved in deploying the PostgreSQL driver in a Kubernetes environment,

  • Creating a Dockerfile and prepackaging the driver to a custom docker image.
  • Modifying the Kubernetes deployment scripts to use the custom docker image.

Creating a Dockerfile and prepackaging the driver to a custom docker image

Please find the Dockerfile created to include the postgresql-42.2.12.jar to the WSO2 API Manager base Docker image.

Dockerfile to include PostgreSQL Driver

Place the postgresql-42.2.12.jar JDBC Driver in the same folder where the Dockerfile is placed.

Run the following command from the directory where the Dockerfile is placed,

docker build -t docker.wso2.com/wso2am1:3.1.0 .

Note that the “.” used in the above command is to specify the current directory.

Executing the above command now we have created a custom docker image docker.wso2.com/wso2am1:3.1.0.

Next step is to modify the Kubernetes deployment scripts.
We will be using the Simplified WSO2 Kubernetes API Manager deployment, the deployment details can be found in the link,

The deployment scripts can be found in the link,

We will be using the wso2am-ga.sh deployment script.

Modifying the Kubernetes deployment scripts to use the custom docker image

Change the image configuration of the wso2am-pattern-1-am-1-deployment deployment in the wso2am-ga.sh script file pointing to the custom built image as below,

containers:
- name: wso2am-pattern-1-am
image: "$image.pull.@.wso2"/wso2am1:3.1.0

We will be only deploying the PostgreSQL JDBC driver to the API Manager deployment, so will only modify the image configuration of wso2am-pattern-1-am-1-deployment. You can change other deployments also if needed.

Change the image configuration of the wso2apim-deployment.yaml file to point to the custom built image as below,

containers:
- name: wso2am-pattern-1-am
image: "$image.pull.@.wso2"/wso2am1:3.1.0

Now that we have made all the necessary changes we need to re-run the deployment scripts to deploy the Docker container with the PostgreSQL Driver.

Thank you for reading.
Cheers!!!

[1] https://github.com/wso2/kubernetes-apim/tree/3.1.x/simple
[2] https://github.com/wso2/kubernetes-apim/tree/3.1.x/simple/deployment-scripts
[3] https://github.com/wso2/kubernetes-apim/blob/3.1.x/simple/deployment-scripts/wso2am-ga.sh
[4] https://github.com/wso2/kubernetes-apim/blob/3.1.x/simple/kubernetes-apim/wso2apim-deployment.yaml

Senior Software Engineer @WSO2, B.Sc.(Hons).Computer Engineering