如何针对不同环境管理 spring-boot 应用程序配置?

How to manage spring-boot application configuration for different environmnets?

我有一个 spring-boot 应用程序,它 运行 在不同的环境中(dev、qa、prod)。为了生成可以在所有环境中 运行 而无需任何修改的不可变构建,我将特定于环境的配置文件打包到生成的 jar 本身中。但这也产生了另一个问题,即向开发团队公开生产数据库凭据。我可以使用外部配置服务器,但现在这对我来说太过分了。

我如何管理这些配置文件以避免此信息泄漏并拥有不可变的构建来支持 CI/CD?

为了防止数据泄露,建议使用 jasypt 加密 username/password。

application connect to database

https://github.com/ulisesbocchio/jasypt-spring-boot

不过,解密密码必须在机器上,所以它应该已经存在,并尽可能安全(例如,不同的用户,或https://github.com/certnanny/KeyNanny

不过,我不会将配置放在 jar 文件中。它不是应用程序逻辑的一部分,它是部署过程的一部分,部署者应该能够轻松地添加新机器。如果用docker,当然不一样了。

在应用程序中保存您的凭据似乎是一种不安全的做法。您可以在外部保存凭据(外部服务器保存机密,或者可能在不同应用程序或环境变量内的同一服务器上)。通过环境变量读取数据将使您的构建保持完整。

如果您使用任何云服务,如 aws 或 pivotal,那么他们有此类服务来存储您的秘密。

我的大部分应用程序配置文件(eq.application.yml)是这样的:

  datasource:
    username: {database_username:root}
    password: {database_password:root123}
    sql-script-encoding: utf-8
    driver-class-name: com.mysql.jdbc.Driver
    url: jdbc:mysql://{database_host:localhost}:3306/dbname?useUnicode=true&characterEncoding=utf-8

如果存在环境变量,应用程序将从环境中加载配置。否则将使用默认值。

在此之后,您可以构建单个包并 运行 无处不在。

在我的例子中,我将应用程序构建成 docker 映像,并且在 kubernetes 中 运行,因此配置属性将存储在 ConfigMaps 和 Secret 中。

当 Pod 运行ning 时,会加载 configmaps 和 secret 到环境变量。

当然,您也可以使用其他工具。

您可以为不同的配置文件创建 yml 文件并在 JVM 参数中指定配置文件。

  1. application.yml
  2. 中的所有配置文件设置通用参数
  3. application-name.yml
  4. 中设置的特定配置文件的参数
  5. 在 JVM 参数中设置配置文件:java -jar -Dspring.profiles.active=name 或在 .conf 文件中:JAVA_OPTS=-Dspring.profiles.active=name
  6. 与配置文件设置数据库参数相同:java -jar -Dspring.datasource.username=name -Dspring.datasource.password=pass

Read more