Externalize domain.xml partially or entirely for Docker images

797 views
Skip to first unread message

J M

unread,
Feb 2, 2018, 10:51:27 AM2/2/18
to Payara Forum
I have 2 types of enterprise apps that I need to create docker images, and I have a question how best to handle per-client settings in domain.xml (notably, JDBC connection settings).

The first type of EAR is common for all clients (ie, no custom modules in the build).  I could create a docker image for each client, as in the following Dockerfile:

FROM payara/server-full:174

COPY client-
domain.xml ${PAYARA_PATH}/glassfish/domains/${PAYARA_DOMAIN}/config/domain.xml
COPY
../../../../resources/sqljdbc4.jar ${PAYARA_PATH}/glassfish/domains/${PAYARA_DOMAIN}/lib
COPY
../../../../resources/activemq-rar-5.12.0.rar $DEPLOY_DIR
COPY services
-ear-1.0-SNAPSHOT.ear $DEPLOY_DIR

EXPOSE
8080 8181

That just seems like overkill to create a docker image for each client when the only difference is a slightly different domain.xml.  Couldn't I just eliminate the COPY of domain.xml in the above Dockerfile, and instead make that swap in docker-compose.yml, like such:

version: '3'

services
:        
           
   
my-services:
        image
: my-services:latest        
        volumes:
           
- "client-domain.xml:
${PAYARA_PATH}/glassfish/domains/${PAYARA_DOMAIN}/config/domain.xml"
        extra_hosts:
           
- "sqlserver:192.168.1.20"

Perhaps ${PAYARA_PATH} and ${PAYARA_DOMAIN} aren't available, and I'd have to hardcode it as /opt/payara41/glassfish/domains/domain1/config/domain.xml.

The second type of EAR is one that is custom to all clients (about 90% common module, 10% custom EJBs).  With this type I see no problem copying the domain.xml into the Docker image, but that mean I need an image for each environment (TEST, STAGE, PROD), which is again overkill.  I could do something in docker-compose.xml like above.

Lastly, I'd like to point out that the extra_hosts setting in the above docker-compose.xml is present so that I can semi-common settings in domain.xml.  I think that's how it works, right?  It doesn't take care of other JDBC values such as database name, port, username, password, etc.  Here is the relevant portion of the domain.xml that I'm trying to make as generic as possible:

<jdbc-connection-pool datasource-classname="com.microsoft.sqlserver.jdbc.SQLServerDataSource" name="MyJDBC" res-type="javax.sql.DataSource">
   
<property name="User" value="myuser"></property>
   
<property name="URL" value="jdbc:sqlserver://"></property>
   
<property name="Password" value="mypass"></property>
   
<property name="DatabaseName" value="TEST_DB"></property>
   
<property name="ServerName" value="sqlserver"></property>
   
<property name="PortNumber" value="1433"></property>
</jdbc-connection-pool>


What are your thoughts?  Am I going about this all wrong?

Mike Croft

unread,
Feb 2, 2018, 12:11:58 PM2/2/18
to Payara Forum
There's a couple of ways that you can improve things here:

  1. post-boot command files
    In the same way as Payara Micro, Payara Server can handle post-boot command files. There's an example in our official docker repo. Basically, if you configure the server through the admin console with the asadmin command recorder on, then the resulting file will contain all the commands which you can then run against the server.

  2. Environment variables
    In Payara Server 172, we enhanced and extended the way that variables can be used to configure the server. You can now use the pattern ${ENV=myVar} in both annotations and the domain.xml to set things like your datasource URL to something like ${ENV=myURL}. The advantage here is that the actual value can be set through Docker (or docker-compose) environment variables. In my opinion, this is the best way to achieve both your goals with Docker.
For each of your client images, you could set your custom ENV variables at the top of the Dockerfiles so that the values will be ready once the rest of the configuration is done and the client starts.

It might also be worthwhile to investigate the MicroProfile Config API, which is included in Payara Server and Micro so you can configure your app in other ways between DEV/TEST/PROD environments:

https://github.com/eclipse/microprofile-config/releases

Do check out our docs on our Config implementation because we have added a few more config sources, so you can even store MicroProfile configuration values in the domain.xml. In the next release, we have added the Kubernetes secrets vault as a configuration source too. Currently, we implement Config 1.1, but this will be Config 1.2 in 181.

Hope that helps!

J M

unread,
Feb 7, 2018, 2:00:43 PM2/7/18
to Payara Forum
That works great. Thanks!

Phillip Ross

unread,
Apr 2, 2018, 1:54:41 AM4/2/18
to Payara Forum

Mike, is the microprofile config api tied into variable substitution with the v4/v5 181 releases?  I was trying to define secrets with the secrets directory config source and thought it would do variable substitution within a datasource defined in web.xml, but it doesn't seem to work.  For my tests i'm running payara server full 4.1.2.181, and I can see the secrets are showing up if I query the config source programatically, but it's just the variable substitution in web.xml that I can't get to work.

On Friday, February 2, 2018 at 12:11:58 PM UTC-5, Mike Croft wrote:

Steve Millidge

unread,
Apr 2, 2018, 7:42:53 AM4/2/18
to Payara Forum
Not yet. It is a long term goal to unify the variable replacement with the microprofile config api.
Reply all
Reply to author
Forward
0 new messages