On the way back I passed by this beautiful cherry tree – you see the picture above. Let’s see if I can host this Kanban software on SAP BTP!
This article explains how to deploy a multi-service application on SAP BTP using Kyma and Kubernetes.
At the end of the tutorial you should be able to login to Wekan and set up beautiful boards like below.
Wekan is a wonderful implementation of Software Kanban based on MongoDB and offering a great flexibility to customize boards, cards and with sufficient APIs to download the data. Moreover, the maintainer of this application kindly provides a docker repository to deploy it as a container!
I tried to build an image and to host it on SAP BTP CloudFoundry (CF) the other day and failed as it is a composition of services: The Wekan application and the MongoDB! To all I know about CF, it won’t support pushing compositions. Also, it has a limitation of port numbers: First, only one port can be exposed per container, second, the port number must be 1000 or above. There is also a restriction in disk quota of 4GB. If this is wrong information, please comment!
So I recalled that with Kyma it should be possible to leverage Kubernetes’ ability to deploy it and that is what I did.
⚠ I’m using Windows so please adjust for Linux or Mac accordingly.
First, we need a SAP BTP account with Kyma activated. There are a few blogs out there so I won’t explain it here. I recommend these:
- Kyma for Dymmies: First Simple App in SAP Cloud Platform, Kyma runtime 🐈 (I love cats!)
- Install the Kubernetes Command Line Tool
Second, we need a local installation of Docker Desktop. Also make sure you have a Docker Hub account registered so that you can push images to Docker Hub.
Third, there is a tool we will need later called Kompose. Please have this ready as well. I guess this is it.
Building the docker image
At first we build our docker image for Wekan. This gives us the possibility to change the settings if we like. Also we will push this to our docker hub account later to make it available for SAP BTP.
Let’s clone the repository from Github into an empty folder on our computer:
git clone https://github.com/wekan/wekan.git
Note that there are two files of interest in the main folder: Dockerfile that defines the “recipe” how the image is to be built and docker-compose.yml that defines how the services work with each other (dependencies).
Let’s drill into the docker-compose.yml for a moment as it helps to understand a later step in this tutorial:
services: wekandb: image: mongo:4.4 container_name: wekan-db restart: always command: mongod --logpath /dev/null --oplogSize 128 --quiet networks: - wekan-tier expose: - 27017 volumes: - wekan-db:/data/db - wekan-db-dump:/dump wekan: image: gunter04/wekan container_name: wekan-app restart: always networks: - wekan-tier build: context: . dockerfile: gunter04/wekan ports: - 3001:8080 environment: - MONGO_URL=mongodb://wekandb:27017/wekan depends_on: - wekandb volumes: wekan-db: driver: local wekan-db-dump: driver: local networks: wekan-tier: driver: bridge
I’ve removed all comments so it becomes clearer. We see 2 services get defined, for the application (wekan) and the database (wekandb). We can also see that wekan depends on wekandb therefore defining the sequence of service instantiation.
We also see that the network definition is shared among the 2 services, therefore establishing a bridge architecture (wekan-tier definition). I also defined the port to be exposed as 3001 but (maybe) this is ultimately not required. We will see later.
We can now build the image (exchange the dot if you are not in the directory of Wekan with the path to it or cd into it to use the dot:
docker build . --tag gunter04/wekan
and then push it to the Docker Hub (in my case gunter04/wekan). You can use this image if you like or adjust accordingly.
docker push gunter04/wekan
Once it’s pushed to the hub (and therefore accessible to SAP BTP) we’re good to go to the next step. You can tag at the time of pushing otherwise it will be latest. If you wonder why you don’t need to authenticate to Docker Hub: It’s because you very likely did already on the docker desktop. You should now see a remote image:
Preparing docker desktop for Kyma on SAP BTP
Now we prepare the docker desktop to work with SAP BTP Kyma, well actually with the Kubernetes cluster below Kyma. But Kyma helps us with this. Let’s enter the SAP BTP and navigate to the subaccount overview that you enabled Kyma with:
We click the link to open up the Kyma dashboard. From there we download the connection details which we will use in the docker desktop.
A yaml-file will be downloaded with details specific to your instance of Kyma. Next let’s check if Docker Desktop has Kubernetes enabled. That is in settings menu ➝ Kubernetes. Check the box to enable it if not already done and wait for it to complete. It can take some minutes.
As for me it never completed and I reset Kubernetes, shut the Docker desktop down, restarted and it worked from there.
If all looks like above, we exchange the standard file in %userprofile%\.kube (for Linux it would be ~/.kube I suppose) called config with the content from the downloaded file from BTP.
Let’s test if that works by reading the context:
kubectl config get-contexts
Output should be something like this:
CURRENT NAME CLUSTER AUTHINFO NAMESPACE * xxxxxxx.kyma.shoot.live.k8s-hana.ondemand.com xxxxxxx.kyma.shoot.live.k8s-hana.ondemand.com OIDCUser
Configuring Kubernetes with Kompose
Do you remember when we looked into the docker-compose.yml? This file explains to docker how to create the container and the sequence of starting the services and how they interact.
Good or bad, this is not how it works with Kubernetes. Kubernetes is to orchestrate many containers (possibly of the same image) at the same time. Therefore it needs to know which services can be created and ended just like that and others (like our database) which should better be saved before ending them. For that a multitude of files is needed.
Good for us, some friendly, clever people created Kompose to generate the required files out of the docker-compose.yml. And sometimes – like for us – this works out of the box without the need to edit these.
Let’s create them! We cd into the wekan folder that we cloned before from git and run:
This generates many yaml-files:
wekan-deployment.yaml wekan-dockerfile-manifest.yaml wekan-service.yaml wekan-wekan-db-dump-persistentvolumeclaim.yaml wekan-wekan-db-persistentvolumeclaim.yaml wekandb-deployment.yaml wekandb-service.yaml wekan_wekan-tier-networkpolicy.yaml
Wow! We will not need all in our last step, though.
Deploying application with Kubernetes and Kyma
Let’s stay at the command line and create a namespace for this deployment:
kubectl create namespace sapblog ➝namespace/sapblog created
Give it any name you prefer of course 😅!
You should now see a new namespace in the Kyma dashboard.
Let’s click on it which navigates us to the resources. Let us now gradually start the Wekan.
kubectl -n sapblog apply -f wekandb-service.yaml ➝service/wekandb created
And let’s check what happened in Kyma:
Let’s create the persistent volume claims next:
kubectl -n sapblog apply -f wekan-wekan-db-dump-persistentvolumeclaim.yaml ➝persistentvolumeclaim/wekan-wekan-db-dump created kubectl -n sapblog apply -f wekan-wekan-db-persistentvolumeclaim.yaml ➝persistentvolumeclaim/wekan-wekan-db created
And also let’s create the MongoDB instance:
kubectl -n sapblog apply -f wekandb-deployment.yaml ➝deployment.apps/wekandb created
We check what happened on Kyma:
We just created a MongoDB on SAP BTP! ✊ It should take like a minute until the status changes from WAITING to RUNNING.
If you want to see what’s going on, click the three dots and then on Logs. Now that the database is running we complete the final steps:
kubectl -n sapblog apply -f wekan-service.yaml ➝service/wekan created kubectl -n sapblog apply -f wekan-deployment.yaml ➝deployment.apps/wekan created
Let’s check Kyma again.
Kyma presents this to us in an overview as well:
Now let’s try out the application! Wait! How? 🤔
We add an API rule for the main service wekan in order to access the kanban board like shown below.
Yay! It works. You can register yourself by clicking “Register” and filling in the fields below. Once you push the button “Register” it gives an error which is ok.
Then click on “sign in” and log in with the credentials you just set. This makes you the admin. Enjoy! Wekan is a magnificent, speedy tool with a roadmap towards future features – Kudos to the team!
We have seen how to push a multi-service application to SAP BTP making use of Kyma, Kubernetes and Kompose. Now we know I had to choose a Kanban application to complement the many Ks. 😁
I’m very confident there are better ways to achieve the same result with Kyma – if you know, let me know in the comments!
Appendix / Q&A / Troubleshooting
Q: KubeCtl will not allow me to get into Kyma!
error: You must be logged in to the server (the server has asked for the client to provide credentials
A: Download a new file through “Get KubeConfig” (see above)
Q: How can I open a command line (shell) in a running container?
A: Get the pods through
kubectl get pod
Then open the according running container by
kubectl exec --stdin --tty <the name of your pod> -- /bin/bash
actually this just opens the first container. You get a hint how to see all containers (in case you have multiple in the same pod). If you can’t use /bin/bash try if /bin/sh is available (depends on the image).
Q: Can I set a default namespace to work with?
A: Yes, to get an overview of all namespaces in Kyma/Kubernetes:
kubectl get namespace
to set a default namespace:
kubectl config set-context --current --namespace=<your namespace>