如何在运行时将数据源密码传递给WebSphere Liberty容器

5
我正在尝试在WebSphere Liberty Profile容器中运行我的应用程序。我希望有一个镜像可以在不同的环境(如dev, st, sit等)上运行。我可以使用env变量在运行时将值传递到容器中。如何在wlp设置中使用这些变量?是否可能?
在server.xml中,我已经定义了数据源,并设置了所有连接字符串、用户名和密码等配置属性。我已经使用此文件构建了镜像。现在,我想通过将值作为env变量传递而不是硬编码在server.xml中,在不同的环境中测试相同的镜像。然而,我无法找到一种方式让server.xml直接读取env变量并替换密码变量。
我尝试的另一种方法是使用bootstrap.properties,这样server.xml就可以从该文件中读取值。但是,在此过程中,我仍需要在构建镜像时提供bootstrap.properties,并且我无法在运行时更改它们的值。
server.xml中的代码如下: 其中,db.url、db.username和db.password在bootstrap.properties中定义,并在构建镜像时打包在其中。
2个回答

5

来自这里

The following predefined variables can be referenced:
* directory properties, see Liberty: Directory locations and properties
* JVM system properties
* process environment variables

If 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 variables

Use 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.

那么,一种可能的解决方案是:

server.xml:

<properties.oracle URL="${env.db_url}" user="${env.db_username}" password="${env.db_password}"/>

只在运行容器时将环境传递给它:

docker run -d -e db_url=xxx -e db_username=xx -e db_password=x your_image

不同的值将传递到不同的容器中,最终以env.格式由server.xml引用。

更新:

从@Lata尝试后得出以下结论:

我尝试了大小写敏感的情况。我得到的是,在server.xml中使用哪种大小写不重要。但是在调用docker run时,你必须只能使用大写字母来工作。

  • server.xml - 大写字母
    • docker run - 大写字母 - 可以运行
    • docker run- 小写字母 - 无法运行。
  • server.xml - 小写字母
    • docker run - 大写字母 - 可以运行。
    • docker run - 小写字母 - 无法运行。

因此,最终的结论应该是:在server.xml中无论使用大写或小写字母都没有关系,但需要将环境变量传递给docker run时只能使用大写字母。由于Docker没有这样的限制,所以肯定是websphere强制执行此限制。


2
这个可以运行,但请确保在两个地方都使用大写变量,例如 env.DB_URL 而不是 env.db_url,并且不要使用点号,例如 db.password,而是使用 DB_PASSWORD - Gas
2
它绝对有效;我正在使用它来创建我的Docker Liberty镜像。我也在使用大写的环境变量,因为我跟随示例而没有考虑到这个细节,并且习惯于环境变量是大写的。但我认为我不会期望大小写有所影响。 - dbreaux
谢谢大家。最终我使用环境变量解决了问题。问题出在密码中有特殊字符,而我忘记将其放在引号中。 - Lata
很高兴你找到了钥匙。 - atline
@atline @Gas @dbreaux。在调用docker run时它起作用了。<properties.oracle URL="${env.DB_URL}" user="${env.DB_USERNAME}" password="${env.DB_PASSWORD}"/> docker run -d -e DB_URL=urlvalue -e DB_USERNAME=unamevalue -e DB_PASSWORD='passvalue' - Lata
显示剩余7条评论

3

虽然@atline的回答对于旧版的Liberty是正确的,但由于问题在Docker容器中运行,它们很可能正在运行一个Liberty版本,该版本从19.0.0.3开始对变量解析有不同的行为。

自19.0.0.3以来,环境变量解析不再需要env前缀,也不需要将变量名大写。如此文档所述:链接

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" />
根据问题,似乎值在bootstrap.properties和环境变量中都被指定,并且bootstrap.properties覆盖环境变量:

您可以使用变量来参数化服务器配置。在解析变量名称时,按照优先级递增的顺序查阅以下来源:

  • server.xml默认变量值
  • 环境变量
  • bootstrap.properties
  • Java系统属性
  • server.xml配置
要从docker中读取它们,需要从bootstrap.properties中删除它们。以您的示例为例:
<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>

如果您从bootstrap.properties中删除db.urldb.passworddb.username的定义,则可以这样启动Docker镜像:
docker run -d -e db_url=xxx -e db_username=xx -e db_password=x your_image

如果您想在没有指定默认值的情况下定义默认值,则可以将以下内容添加到您的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"/>

如果您想将密码进行编码或加密,以避免明文存储,可以使用以下方法:

securityUtility encode --encoding=[xor|aes]

运行以下命令可获取所有选项的完整帮助:

securityUtility help encode

谢谢@Alasdair。使用环境变量对我有用。我们仍在使用版本19.0.0.2,所以我必须使用env前缀。 - Lata

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接