Deploying WebProtege on Azure Kubernetes Service (AKS)

Matthew Manela
4 min readAug 24, 2020

My team at Microsoft is attempting to model and relate the many logical and physical entities that exist across Azure. This is a large and complicated task and we make use of Ontology specialists to help guide the modeling work.

Ontology (n): a set of concepts and categories in a subject area or domain that shows their properties and the relations between them.

Working with Ontologists for the first time exposed me to a new world of terminology and tools. They model our project in a format called OWL (Web Ontology Language). This provides a language to describe objects and represent the relationships between them.

A popular editor for authoring OWL is called WebProtégé. This is developed at Stanford and provides a GUI to make it easy to create and explore an OWL based ontology.

WebProtégé UI + Pizza

WebProtege Kubernetes on AKS

When onboarding Ontologists onto our team, we were asked to host an instance of the WebProtege tool to enable them to work together and collaborate. There exists a shared instance hosted by Stanford but we needed to host it internally for privacy reasons.

The WebProtege’s GitHub repo has instructions for deploying using Docker Compose, but I decided to deploy this using Kubernetes on Azure Kubernetes Service (AKS).

WebProtege requires two containers: a MongoDB storage layer and the WebProtege app itself.

MongoDB

To deploy MongoDB we need three Kubernetes objects

  1. Deployment — deploys the MongoDB container to Pods and determines how many replicas (defaulted to one).
  2. Service — provides access to the pod.
  3. PersistentVolumeClaim — ensures the MongoDB data is stored somewhere that will persist after restarts.

I defined them together in one YAML file (mongo.yaml):

apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: mongo-pvc
spec:
accessModes:
- ReadWriteOnce
resources:
requests:
storage: 256Mi
---
apiVersion: v1
kind: Service
metadata:
name: mongo
spec:
selector:
app: mongo
ports:
- port: 27017
targetPort: 27017
---
apiVersion: apps/v1
kind: Deployment
metadata:
name: mongo
spec:
selector:
matchLabels:
app: mongo
template:
metadata:
labels:
app: mongo
spec:
containers:
- name: mongo
image: mongo:4.1-bionic
ports:
- containerPort: 27017
volumeMounts:
- name: storage
mountPath: /data/db
volumes:
- name: storage
persistentVolumeClaim:
claimName: mongo-pvc

The most interesting part is the PersistentVolumeClaim. This provides persisted storage for MongoDB. When deploying on AKS this creates an instance of Azure Disk Storage behind the scenes with the requested amount of memory.

WebProtege App

For the WebProtege app we need two Kubernetes objects

  1. Deployment — configures and deploys the container for the WebProtege app.
  2. Service — provides external access to the app using the LoadBalancer service type.

These two are defined together in the file protege.yaml:

apiVersion: v1
kind: Service
metadata:
name: protege
annotations:
service.beta.kubernetes.io/azure-dns-label-name: myprotege
spec:
selector:
app: protege
ports:
- port: 80
targetPort: 8080
type: LoadBalancer
---
apiVersion: apps/v1
kind: Deployment
metadata:
name: protege
spec:
replicas: 1
selector:
matchLabels:
app: protege
template:
metadata:
labels:
app: protege
spec:
containers:
- name: protege
image: protegeproject/webprotege
ports:
- containerPort: 8080
env:
- name: MONGO_URL
value: mongodb://mongo:27017/dev
- name: webprotege.mongodb.host
value: mongo
imagePullPolicy: Always

In the Deployment object I reference the port and name defined in the MongoDB deployment and pass that into an environment variable for the WebProtege container.

The Service object in this case is of type LoadBalancer which enables external access to the Pods. By default, AKS will provision a PublicIP address for this service. However, this is not a fixed static IP and if you delete and re-provision your service it may change. For that reason you can add an annotation that tells Azure to provision a DNS name for the PublicIP address.

service.beta.kubernetes.io/azure-dns-label-name: myprotege

This will result in a url like myprotege.westus2.cloudapp.azure.com. This allows persistent access even if the ip address changes.

And deploy on AKS …

With those in-place you can deploy a fresh Kubernetes cluster on AKS with the following script (assuming you already have a subscription configured) using az commandline client.

#!/bin/bashecho "Login to your azure account"
az login
echo "Select your subscription"
az account set -s "YOUR_SUBSCRIPTION_ID"
echo "Create Resource Group"
az group create --name myprotege --location westus2
echo "Create AKS Cluster"
az aks create --resource-group myprotege --name myprotegeAKS --node-count 1 --generate-ssh-keys
echo "Load Credential for KubeCtl to use"
az aks get-credentials --resource-group myprotege --name myprotegeAKS
echo "Deploy Mongo"
kubectl apply -f mongo.yaml
echo "Deploy Protege"
kubectl apply -f protege.yaml

Once this finishes you should have a running container of WebProtege and MongoDB. The next step is to follow the initial configuration step to create an admin account from their docs. For this step you need to get shell access to the container running the instance of WebProtege.

To do that first get the list of pods:

> kubectl get pods
NAME READY STATUS RESTARTS AGE
mongo-d86dd97bd-rc9zq 1/1 Running 0 2m10s
protege-678fb4955b-xf64m 1/1 Running 0 2m10s

And then open a shell into the pod:

> kubectl exec -it protege-678fb4955b-xf64m -- /bin/bash

Once in there you can run the required configuration command:

# java -jar /webprotege-cli.jar create-admin-account

And that’s it! You should now have a running and configured instance of WebProtege.

All you need to do is go to http://myprotege.westus2.cloudapp.azure.com/#application/settings (or whatever you configured above) and finish the final UI steps.

--

--