Reputation: 53
I am trying to run my app in websphere liberty profile container. I want to have 1 image which can be run on diff env(dev, st, sit etc). I can use env variable to pass the values at runtime to the container. How to use those in wlp settings? Is this possible?
In the server.xml, I have defined the datasource with all config properties like connection string, username and password. I have built the image using this file. Now, I want to test the same image in different env by passing the values as env variable instead of hardcoding in the server.xml. I couldn't find a way where server.xml can read the env var directly and replace the password variable. Other way I tried is using the bootstrap.properties and so server.xml can read the values from that file. But here also, I have to provide the bootstrap.properties during image building and I can't change the values during runtime.
lines in server.xml:
<dataSource name="XYZ" jndiName="jdbc/xyz" transactional="false">
<jdbcDriver id="OracleJdbcDriver" libraryRef="xyzLib"/>
<properties.oracle URL="${db.url}" user="${db.username}" password="${db.password}"/>
</dataSource>
db.url, db.username and db.password are defined in bootstrap.properties which is packaged in the image during build time.
Upvotes: 5
Views: 2112
Reputation: 31664
From this:
The following predefined variables can be referenced:
* directory properties, see Liberty: Directory locations and properties
* JVM system properties
* process environment variablesIf the same variable is specified in multiple places, the precedence is as follows:
* variables in bootstrap.properties override the process environment variables
* variables in server.xml, or included XML files, override the variables in bootstrap.properties and process environment variablesUse process environment variables in the configuration. Process environment variables are available if you use the env. configuration variable prefix, for example:
<fileset dir="${env.LIBRARY_DIR}" includes="*.jar"/>
For more information on specifying environment variables, see Customizing the Liberty environment.
Then, a probable solution is:
server.xml:
<properties.oracle URL="${env.db_url}" user="${env.db_username}" password="${env.db_password}"/>
Pass environment to container just when run it:
docker run -d -e db_url=xxx -e db_username=xx -e db_password=x your_image
Then, different values will be passed to different containers & finally referenced by server.xml
with env.
format.
UPDATE:
From @Lata 's try as next:
I tried the scenario with capital and small letters. What I got is it doesn't matter which casing you use in server.xml. But while calling the docker run, you have to pass the variables in CAPS only to work.
So, the final conclusion should be: no matter CAPS or LOW case letter in server.xml
, but need to pass CAPS env to docker run
. As docker not have such limits, so definitely websphere
enforce this limit.
Upvotes: 5
Reputation: 3211
While the response from @atline is correct for older releases of Liberty since the question is running in Docker containers they are very likely running on a version of Liberty since 19.0.0.3 which has different behaviour regarding variable resolution.
Since 19.0.0.3 environment variable resolution has not required the env. prefix and doesn't require the variable name to be in upper case. As documented at this link
Environment variables can be accessed as variables. From 19.0.0.3, they can be accessed directly by referencing the environment variable name. If the variable cannot be resolved the following transformations on the environment variable name is tried:
- Replace all non-alpha num characters with
_
- Change all characters to upper case.
If you enter ${my.env.var} in server.xml it will look for environment variables with the following names:
- my.env.var
- my_env_var
- MY_ENV_VAR
When using a Liberty release older than 19.0.0.3, environment variables can be accessed by adding env. to the start of the environment variable name:
<httpEndpoint id="defaultHttpEndpoint" host="${env.HOST}" httpPort="9080" />
Based on the question it seems that the value is being specified in bootstrap.properties as well as in environment variables and bootstrap.properties overrides environment variables:
You can parameterize server config using variables. When resolving variable names the following sources are consulted in increasing order of precedence:
- server.xml default variable values
- environment variables
- bootstrap.properties
- Java system properties
- server.xml config
To get them read from docker you need to remove them from bootstrap.properties. Given your example:
<dataSource name="XYZ" jndiName="jdbc/xyz" transactional="false">
<jdbcDriver id="OracleJdbcDriver" libraryRef="xyzLib"/>
<properties.oracle URL="${db.url}" user="${db.username}" password="${db.password}"/>
</dataSource>
if you remove the definition of db.url
, db.password
and db.username
from bootstrap.properties
then you can start a docker image thus:
docker run -d -e db_url=xxx -e db_username=xx -e db_password=x your_image
If you want to have defaults defined in case those are not specified then you can add this to your server.xml
:
<variable name="db.url" defaultValue="jdbc:XXX"/>
<variable name="db.username" defaultValue="testUser"/>
<variable name="db.password" defaultValue="testPassword that will be encoded or encrypted"/>
If you want to encode or encrypt the password so it isn't in plain text you can use:
securityUtility encode --encoding=[xor|aes]
the full help for all the options is available by running:
securityUtility help encode
Upvotes: 3