How to separate application config from AP in container on Kuberetes?

6/28/2019

I want to deploy a application which use an extenal config on Kubernetes. I built a spring boot application to a war file and put it into websphere liberty. Then put application.properties in /config/config ( /config is shortcut of /opt/ibm/wlp/usr/servers/defaultServer) which I want my application to use. I write a Dockerfile as below:

FROM websphere-liberty:19.0.0.6-javaee8
USER root
RUN mkdir -p /ibank-pv && chown -R 1001:0 /ibank-pv
RUN mkdir -p /config/config/ && chown -R 1001:0 /config/config
COPY --chown=1001:0 ibank.war /config/apps/
COPY --chown=1001:0 server.xml /config
COPY --chown=1001:0 application.properties /config/config/
USER 1001
CMD ["/opt/ibm/wlp/bin/server","run","defaultServer"]

Here is my server.xml. I set ${server.config.dir}/config as a config resource folder.

<?xml version="1.0" encoding="UTF-8"?>
<server description="new server">
    <featureManager>
        <feature>javaee-8.0</feature>
    </featureManager>

    <basicRegistry id="basic" realm="BasicRealm">
        <!-- <user name="yourUserName" password="" />  -->
    </basicRegistry>

    <httpEndpoint id="defaultHttpEndpoint"
                  httpPort="9080"
                  httpsPort="9443" />

    <applicationManager autoExpand="true"/>

    <library id="configResources">
        <folder dir="${server.config.dir}/config" />
    </library>

    <application location="ibank.war">
        <classloader privateLibraryRef="configResources" />
    </application>
</server>

And I add these code to read the application.properties in ${server.config.dir}/config.

public class IbankServlet extends HttpServlet {

    private static final long serialVersionUID = 7526471155622776147L;

    private final Properties config;

    public IbankServlet() throws Exception {
        InputStream is = getClass().getResourceAsStream("application.properties");
        config = new Properties();
        config.load(is);
    }

}

However, when I start the server my application, it still read the application.properties which is in war file. What I have to do let my application use application.properties in ${server.config.dir}/config.

-- Eric
docker
java
kubernetes
spring-boot
websphere-liberty

1 Answer

6/28/2019

Is the issue that getClass().getResourceAsStream("relative-path") looks in the Java package of that specified class? That is, whatever subdirectory corresponds to the Java package of IbankServlet. In other words, is your application.properties within the WAR file buried down in a package subdirectory?

If so, you'll need to either change to getClass().getResourceAsStream("/application.properties") (with the leading slash), and move it to the classpath root in your WAR file, or have your Docker file copy it down into the correct subdirectory.

However, if your IbankServlet is actually not in a Java package at all, this probably isn't the issue.)

(But also, I admit, I'm not certain of the precedence if a file exists in both your WAR and in a "shared library".)

-- dbreaux
Source: StackOverflow