Vaadin app with persistent PostgreSQL in Kubernetes
We’ll build on the 2 Vaadin Apps 1 Kubernetes article; this time we’ll add a persistent database PostgreSQL to the mix. We’ll deploy the jdbi-orm-vaadin-crud-demo app which has the capability of running with either in-memory H2, or a remote PostgreSQL database. We’ll learn how services talk to each other by the help of the DNS plugin, and how to make PostgreSQL database files persistent using the hostpath-storage plugin.
DNS
We’ll use the microk8s DNS plugin:
$ microk8s enable dns
This will allow the app to connect to the postgres
service (which we’ll create in a minute)
via jdbc:postgresql://postgres:5432/postgres
, as opposed to having type in an IP address of the service.
Persistent Storage
Data in PostgreSQL needs to be persisted for long term storage. The default location for
storage in PostgreSQL is /var/lib/postgresql/data
. However, Kubernetes pods are designed
to have ephemeral storage, which means once a pod dies all the data within the pod is lost.
To mitigate against this, Kubernetes has the concept of volumes.
You can learn the concepts from excellent Kubernetes Volumes Explained
by Nana.
We’ll use the microk8s hostpath-storage add-on which creates the volumes on a local machine, but that’s more than enough for our purposes. It creates the persistent volume automatically for us; therefore we only need to create a Persistent Volume Claims and microk8s will automatically connect them to the local volume.
To enable the plugin, run:
$ microk8s enable hostpath-storage
Putting it all together
The entire setup is configured in one Kubernetes configuration file: kubernetes-app.yaml Please see the contents of the file for further explanation.
When everything is up-and-running, you should be able to browse to localhost and see the app up-and-running.
You can view the database files according to the hostpath-storage docs;
$ mkctl get pvc -n jdbi-orm-vaadin-crud-demo
NAME STATUS VOLUME CAPACITY ACCESS MODES STORAGECLASS AGE
postgres-pvc Bound pvc-8c8879fd-c0f4-4b94-8677-b5885babe5a1 512Mi RWO microk8s-hostpath 18m
$ mkctl describe pv pvc-8c8879fd-c0f4-4b94-8677-b5885babe5a1
...
Path: /var/snap/microk8s/common/default-storage/jdbi-orm-vaadin-crud-demo-postgres-pvc-pvc-8c8879fd-c0f4-4b94-8677-b5885babe5a1
...
$ sudo ls -la /var/snap/microk8s/common/default-storage/jdbi-orm-vaadin-crud-demo-postgres-pvc-pvc-8c8879fd-c0f4-4b94-8677-b5885babe5a1
When something fails
If the app fails to start because Postgres was unavailable for too long, you can
see that in the app logs. Either run the Kubernetes Dashboard via
microk8s dashboard-proxy
then point your browser according to the instructions printed
in the console. Make sure to select the jdbi-orm-vaadin-crud-demo
namespace, browse
to the Pods, deployment
and view its logs.
Alternatively, do the same thing with the command-line:
$ mkctl get pods --namespace jdbi-orm-vaadin-crud-demo
NAME READY STATUS RESTARTS AGE
deployment-6bc9b6b675-9x7m4 1/1 Running 0 7m27s
postgresql-deployment-6cb8657544-bxgtz 1/1 Running 0 10m
$ mkctl logs deployment-6bc9b6b675-9x7m4 -n jdbi-orm-vaadin-crud-demo
2023-04-24 05:53:00.689 [main] INFO com.github.mvysny.vaadinboot.VaadinBoot - Starting App
...
If you see the database-related exceptions, the easiest way is to restart the deployment:
mkctl rollout restart deployment deployment -n jdbi-orm-vaadin-crud-demo