<p>I have a spring boot application with two profiles, dev and prod, my docker file is:</p>

<pre><code>FROM openjdk:8-jdk-alpine
VOLUME /tmp
ARG DEPENDENCY=target/dependency
COPY ${DEPENDENCY}/BOOT-INF/lib /app/lib
COPY ${DEPENDENCY}/META-INF /app/META-INF
COPY ${DEPENDENCY}/BOOT-INF/classes /app
ENTRYPOINT ["java","-Dspring.profiles.active=dev","-cp","app:app/lib/*","com.my.Application"]
</code></pre>

<p>please not that, when building the image,  I specify the entrypoint as command line argument.</p>

<p>This is the containers section of my kubernetes deployment where I use this image:</p>

<pre><code>containers:
  - name: myapp
    image: myregistry.azurecr.io/myapp:0.1.7
    imagePullPolicy: "Always"
    ports:
    - containerPort: 8080
      name: myapp
    readinessProbe:
      httpGet:
        path: /actuator/health
        port: 8080
      timeoutSeconds: 3
      periodSeconds: 20
      failureThreshold: 3
</code></pre>

<p>It works  but has a major flaw: how can I now switch to the production environment without rebuilding the image? </p>

<p>The best would be to remove that ENTRYPOINT in my docker file and give this configuration in my kubernetes yml so that I could always use the same image...is this possible?</p>

<p>edit: I saw that there is a lifecycle istruction but note that I have a readiness probe based on the spring boot's actuator. It would always fail if I used this construct.</p>

Phate
<p>Rather than putting <code>spring.profiles.active</code> in dockerfile in the entrypoint.</p>

<p>Make use of <a href="https://kubernetes.io/docs/tasks/configure-pod-container/configure-pod-configmap/" rel="nofollow noreferrer">configmaps</a> and <a href="https://docs.spring.io/spring-boot/docs/current/reference/html/common-application-properties.html" rel="nofollow noreferrer">application.properties</a>.</p>

<p>Your ENTRYPOINT in dockerfile should look like:</p>

<pre><code>ENTRYPOINT ["java","-cp","app:app/lib/*","com.my.Application","--spring.config.additional-location=/config/application-dev.properties"]
</code></pre>

<p>Create a configmap that acts as application.properties for your springboot application</p>

<pre><code>---
apiVersion: v1
kind: ConfigMap
metadata:
  name: myapp-config
  namespace: flow
data:
  application-dev.properties: |
    spring.application.name=myapp
    server.port=8080
    spring.profiles.active=dev
</code></pre>

<p><em>NOTE: Here we have specified spring.profiles.active.</em></p>

<p>In containers section of my kubernetes deployment mount the configmap inside container that will act as application.properties.</p>

<pre><code>containers:
  - name: myapp
    image: myregistry.azurecr.io/myapp:0.1.7
    imagePullPolicy: "Always"
    command: ["java","-cp","app:app/lib/*","com.my.Application","--spring.config.additional-location=/config/application-dev.properties"]
    ports:
    - containerPort: 8080
      name: myapp
    volumeMounts:
    - name: myapp-application-config
      mountPath: "/config"
      readOnly: true
    volumes:
    - name: myapp-application-config
      configMap:
        name: myapp-config
        items:
        - key: application-dev.properties
          path: application-dev.properties
    readinessProbe:
      httpGet:
        path: /actuator/health
        port: 8080
      timeoutSeconds: 3
      periodSeconds: 20
      failureThreshold: 3
</code></pre>

<p><em>NOTE: <code>--spring.config.additional-location</code> points to location of application.properties that we created in configmaps.</em></p>

<p>So making use of configmaps and application.properties one can override any configuration of your application wihtout rebuilding the image.</p>

<p>If you want to add a new config or update value of existing config, just make appropriate changes in configmap and <code>kubectl apply</code> it. Then scale down and scale up your application pod, to bring the new config in action.</p>

<p>Hope this helps.</p>
