Setup of spring boot application & initialization of PostgreSQL database on Kubernetes – PART 1

  • How to deploy a containerized spring boot application , with PostgreSQL as database on minikube.
  • This post will also share details on how to initialize the database with tables and data during the initialization process.
  • Will use a spring boot application order service with a REST endpoint to fetch customer details
    • GET /customers
  • It uses spring JPA to access PostgreSQL
  • Details of the service –
  • This article will demonstrate deploying this service on Minikube , More details on minikube can be found at-
  • Key steps for this deployment process are
    • Building a docker image of order-service & upload to docker repository
    • Writing Kubernetes deployment file to initialize and run database
    • Writing Kubernetes deployment file for order-svc
    • Testing the service

Step 1: Building a docker image of order-service & uploading to docker repository

  • Build the application to generate jar file
    • mvn clean install -DskipTests
  • If you want to run this application is local , you will have to update the file with database details
  • Create a docker image for the service , refer to Dockerfile
FROM openjdk:8-jdk-alpine
RUN mkdir -p /app/
RUN mkdir -p /app/logs/
ADD target/order-0.0.1-SNAPSHOT.jar /app/app.jar
ENTRYPOINT ["java","","", "-jar", "/app/app.jar"]
  • Dockerfile has mainly instructions to add openjdk 8 image, expose port 8080 and add the generated jar file from previous step to the image
  • To build an image with the name order-svc-k8 from the Dockerfile , run the below command
    • docker build -t raje/order-svc-k8 .
  • Once the above step is done you can check the image with docker images command
  • To push this image to docker repository, give the command docker push raje/order-svc-k8
  • At this stage, we have built our spring boot app, dockerized it and uploaded to the docker repository

Step 2: Writing Kubernetes deployment file to initialize and run database

  • For PostgreSQL, we will use the docker image . Link to repo –
  • Other 2 important use cases of this demo are
    • Mount a path on host , so that the data can be retrieved even if the cluster goes down
    • Initialize database with table and scripts
  • In order to mount a persistent storage, we will have to deploy a resource type of Persistent Volume and Persistent Volume Claim
  • Since we need a persistent storage for PostgreSQL to store data, we will provision the storage using Persistent Volume yaml
apiVersion: v1
kind: PersistentVolume
  name: postgresql-claim0
    type: local
  storageClassName: manual
    storage: 1Gi
    - ReadWriteOnce
    path: "/Users/rajeshp/docker/postgres/docker-pg-vol/data"
  • Above yaml is for PersistentVolume object , which has details of host path , storage class , size etc. The name defined for this is – postgresql-claim0
  • Persistent volumes have a lifecycle that is independent of any individual pod that uses the storage.
  • In order for our application to consume this storage space, we will have to request it using a Persistent Volume Claim request.
  • yaml for Persistent Volume Claim
apiVersion: v1
kind: PersistentVolumeClaim
  name: postgresql-claim0
    app: postgresql
    tier: database
    - ReadWriteOnce
      storage: 100Mi
  • Next we want to build a configuration map object, which will have our database initialization scripts
  • Configuration maps are kubernetes objects which are used to store non-confidential data in key-value pairs
apiVersion: v1
kind: ConfigMap
  name: postgresql-initdb-config
  init.sql: |
        customer_id bpchar NOT NULL,
        company_name character varying(40) NOT NULL,
        contact_name character varying(30),
        contact_title character varying(30),
        address character varying(60),
        city character varying(15),
        region character varying(15),
        postal_code character varying(10),
        country character varying(15),
        phone character varying(24),
        fax character varying(24)

 INSERT INTO customers VALUES ('ALFKI', 'Alfreds Futterkiste', 'Maria Anders', 'Sales Representative', 'Obere Str. 57', 'Berlin', NULL, '12209', 'Germany', '030-0074321', '030-0076545');
  • Since our order service will need to access this database, we will need a Kubernetes service object
  • Service is responsible for enabling network access to a set of pods
apiVersion: v1
kind: Service
  name: postgresql
    app: postgresql
    tier: database
    - port: 5432
      targetPort: 5432
    app: postgresql
    tier: database
  • Services select Pods based on their labels. When a network request is made to the service, it selects all Pods in the cluster matching the service’s selector, chooses one of them, and forwards the network request to it.
  • Next, we need the deployment object.
apiVersion: apps/v1
kind: Deployment
  name: postgresql
    app: postgresql
    tier: database
      app: postgresql
    type: Recreate
        app: postgresql
        tier: database
        - name: postgresql
          image: postgres:12
          imagePullPolicy: "IfNotPresent"
            - name: POSTGRES_DB
              value: northwind
            - name: POSTGRES_USER
              value: postgres
            - name: POSTGRES_PASSWORD
              value: changeme
            - containerPort: 5432
              name: postgresql
            - name: postgresql-claim0
              mountPath: /var/lib/postgresql/data

            - mountPath: /docker-entrypoint-initdb.d
              name: postgresql-initdb
        - name: postgresql-claim0
            claimName: postgresql-claim0

        - name: postgresql-initdb
            name: postgresql-initdb-config
  • Key elements of the deployment yaml
    • Deploys postgres:12 container
    • Have environment variables , which has the database name, user and password
    • Mounts the persistent volume , defined using Persistent volume object
    • Passes the configmap value for docker to execute
  • Bring minikube up by issuing command: minikube start
  • Let us now deploy all the kubernetes resources by giving following commands
kubectl apply -f postgresql-claim0-persistentvolume.yaml
kubectl apply -f postgresql-claim0-persistentvolumeclaim.yaml
kubectl apply -f postgresql-initial-data-configmap.yamlkubectl kubectl apply -f postgresql-deployment.yaml
kubectl apply -f postgresql-service.yaml
  • You can check status by kubectl get all command
  • In case you want to check the logs of database pod, you can check by issuing this command kubectl logs pod/postgresql-7bf5994f6f-kv5gs . Please replace the pod name with your pod name
  • Let us now verify this deployment , by connecting to database. Commands for the operations are –kubectl exec -it pod/postgresql-7bf5994f6f-kv5gs bash
  • Replace pod name with your pod name in the above command
  • Connect to postgres – psql -U postgres
  • Connect to northwind database – \c northwind
  • Check the tables – \dt
  • Check if database is initialized by executing – select * from customers;

Next steps of deploying the spring boot application is available in the Part 2 .

Thank You !!

2 thoughts on “Setup of spring boot application & initialization of PostgreSQL database on Kubernetes – PART 1

Leave a Reply