<p>I have a springboot app which I want to deploy on Kubernetes (I'm using minikube) with a custom context path taken from the environment variables.</p>

<p>I've compiled an app.war file. exported an environment variable in Linux as follow: </p>

<p><code>export SERVER_SERVLET_CONTEXT_PATH=/app</code> </p>

<p>And then started my app on my machine as follow: </p>

<p><code>java -jar app.war --server.servlet.context-path=$(printenv CONTEXT_PATH)</code></p>

<p>and it works as expected, I can access my app throw browser using the url <strong>localhost:8080/app/</strong></p>

<p>I want to achieve the same thing on minikube so I prepared those config files:</p>

<hr>

<ul>
<li><p>Dockerfile:</p>

<pre><code>FROM openjdk:8
ADD app.war app.war
EXPOSE 8080
ENTRYPOINT ["java", "-jar", "app.war", "--server.servlet.context-path=$(printenv CONTEXT_PATH)"]
</code></pre></li>
</ul>

<hr>

<ul>
<li><p>deployment config file:</p>

<pre><code>apiVersion: apps/v1
kind: Deployment
metadata:
  name: esse-deployment-1
  labels:
    app: esse-1
spec:
  replicas: 1
  selector:
    matchLabels:
      app: esse-1
  template:
    metadata:
      labels:
        app: esse-1
    spec:
      containers:
      - image: mysql:5.7
        name: esse-datasource
        ports:
        - containerPort: 3306
        env: 
        - name: MYSQL_ROOT_PASSWORD
          value: root 
      - image: esse-application
        name: esse-app
        imagePullPolicy: Never
        ports:
        - containerPort: 8080
        env:
        - name: server.servlet.context-path
          value: /esse-1
      volumes:
        - name: esse-1-mysql-persistent-storage
          persistentVolumeClaim:
            claimName: mysql-persistent-storage-claim

---

apiVersion: v1
kind: Service
metadata:
  name: esse-service-1
  labels:
    app: esse-1
spec:
  selector:
    app: esse-1
  ports:
    - protocol: TCP
      port: 8080
      targetPort: 8080
  type: NodePort
</code></pre></li>
</ul>

<p>However, the java container inside the pod fails to start and here's the exception is thrown by spring: </p>

<blockquote>
  <p>Initialization of bean failed; nested exception is
  java.lang.IllegalArgumentException: ContextPath must start with '/'
  and not end with '/'</p>
</blockquote>

<p>Make use of <a href="https://kubernetes.io/docs/tasks/configure-pod-container/configure-pod-configmap/" rel="noreferrer">configmaps</a>.</p>

<p>The configmap will holds application.properties of your springboot application.</p>

<pre><code>---
apiVersion: v1
kind: ConfigMap
metadata:
  name: esse-config
data:
  application-dev.properties: |
    spring.application.name=my-esse-service
    server.port=8080
    server.servlet.context-path=/esse-1
</code></pre>

<p><strong><em>NOTE:</strong> <code>server.servlet.context-path=/esse-1</code> will override context-path of your springboot application.</em></p>

<p>Now refer this configmap in your deployment yaml.</p>

<pre><code>---
apiVersion: apps/v1
kind: Deployment
metadata:
  name: esse-deployment-1
  labels:
    app: esse-1
spec:
  replicas: 1
  selector:
    matchLabels:
      app: esse-1
  template:
    metadata:
      labels:
        app: esse-1
    spec:
      containers:
      - image: mysql:5.7
        name: esse-datasource
        ports:
        - containerPort: 3306
        env: 
        - name: MYSQL_ROOT_PASSWORD
          value: root 
      - image: esse-application
        name: esse-app
        imagePullPolicy: Never
        command: [ "java", "-jar", "app.war", "--spring.config.additional-location=/config/application-dev.properties" ]
        ports:
        - containerPort: 8080
        volumeMounts:
        - name: esse-application-config
          mountPath: "/config"
          readOnly: true
      volumes:
      - name: esse-application-config
        configMap:
          name: esse-config
          items:
          - key: application-dev.properties
            path: application-dev.properties
      - name: esse-1-mysql-persistent-storage
        persistentVolumeClaim:
          claimName: mysql-persistent-storage-claim
</code></pre>

<p><strong><em>NOTE:</strong> Here we are mounting configmap inside your springboot application container at <code>/config</code> folder. Also <code>--spring.config.additional-location=/config/application-dev.properties</code> is pointing to the application.properties config file.</em></p>

<p>In future if you want to add any new config or update the value of existing config that just make the change in configmap and <code>kubectl apply</code> it. Then to reflect those new config changes, just scale down and scale up the deployment.</p>

<p>Hope this helps.</p>
