Technology Blogs by SAP
Learn how to extend and personalize SAP applications. Follow the SAP technology blog for insights into SAP BTP, ABAP, SAP Analytics Cloud, SAP HANA, and more.
Showing results for 
Search instead for 
Did you mean: 
Product and Topic Expert
Product and Topic Expert

Dear readers, it is spring in Tokyo! 🌸Cherry blossom is in full bloom 🌸 Yet another rainy Sunday!

I therefore decided to go out, pay a visit to my favorite bakery, get a coffee and think of some alternative program. And there was my idea! 😁

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.

Flow of activities in this blog post

At the end of the tutorial you  should be able to login to Wekan and set up beautiful boards like below.

Wekan example setup for our blog post hosted on SAP BTP with Kyma


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:

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

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:

image: mongo:4.4
container_name: wekan-db
restart: always
command: mongod --logpath /dev/null --oplogSize 128 --quiet
- wekan-tier
- 27017
- wekan-db:/data/db
- wekan-db-dump:/dump

image: gunter04/wekan
container_name: wekan-app
restart: always
- wekan-tier
context: .
dockerfile: gunter04/wekan
- 3001:8080
- MONGO_URL=mongodb://wekandb:27017/wekan
- wekandb

driver: local
driver: local

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:

Docker Desktop: List of remote images on Docker Hub

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:

SAP BTP: Subaccount overview with link to Kyma dashboard

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.

Connection details for Docker Desktop: Download from Kyma dashboard (upper right corner)

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
* 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:
kompose convert

This generates many yaml-files:

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.

Kyma dashboard: Created namespace is shown

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:

Kyma dashboard: Wekan database service created

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:

Kyma dashboard: MongoDB instance created in a pod

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 dashboard: Wekan running for application and database

Kyma presents this to us in an overview as well:

Kyma dashboard: Deployments and Pods overview

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.

Deployed Wekan through Kyma on SAP BTP: Registration process

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>