【问题标题】:SpringBoot project, Environment Variable in application.yml always emptySpringBoot项目,application.yml中的环境变量始终为空
【发布时间】:2019-10-29 04:13:03
【问题描述】:

我正在尝试运行一个使用 docker-compose 运行的 SpringBoot 项目。我使用docker-compose up 开始了它的依赖项(Redis、MongoDB 和 RabbitMQ)

我正在构建项目并使用这些命令运行它 mvn clean package -DskipTests && mvn spring-boot:run

我一直有这些错误:

Error processing condition on org.springframework.boot.autoconfigure.security.oauth2.client.OAuth2RestOp erationsConfiguration$RequestScopedConfiguration

Caused by: java.lang.IllegalArgumentException: Could not resolve placeholder 'OAUTH_CLIENTID' in value "${OAUTH_CLIENTID}"

在 docker-compose 文件中,环境变量的值在 environment 部分中定义。

 environment:
      - RABBIT_HOST=rabbitstomp
      - RABBIT_USER=guest
      - RABBIT_PASS=user
      - MONGO_HOST=mongodb://localhost:27017
      - OAUTH_CLIENTID=nz-kek
      - OAUTH_CLIENT_SECRET=DzXZxeOZOJHFZIUhObSpsne
      - SSO_HOST=https://webweb.com
      - CORS_HOSTS=HOST1,HOST2
      - SES_HOST=ses
      - SES_PORT=6000
      - REDIS_HOST=localhost
      - REDIS_PORT=6379 

这就是 application.yml 的样子:

     spring.data.mongodb:
  database: ${DB_NAME} #notificationdb
  uri: ${MONGO_HOST}
security:
  oauth2:
    resource:
      jwk:
        key-set-uri: ${auth-server:${SSO_HOST}}/keys
      token-info-uri: ${auth-server:${SSO_HOST}}/userinfo
    client:
      client-id: ${OAUTH_CLIENTID}
          client-secret: ${OAUTH_CLIENT_SECRET}` 

那么在没有 docker-compose 的情况下运行项目时,我应该将值放在 application.yml 中吗?

我也试过mvn spring-boot:run -Dspring-boot.run.arguments=--path.to.value=value1,但我不确定路径应该如何与key-set-uri: ${auth-server:${SSO_HOST}}/keys等变量一起使用

【问题讨论】:

  • 你在运行docker,但是在本地启动Spring Boot……那应该怎么看docker环境变量呢?
  • 该应用程序应该以docker-compose 启动,并且环境变量在我原来的帖子中提到的docker-compose 文件中定义。我要问的是,在将应用程序作为 Spring Boot 应用程序启动时(使用 mvn spring-boot:runjava -jar),是否可以传递这些参数,例如 key-set-uri: ${auth-server:${SSO_HOST}}/keys
  • 它们可用,但要在 docker 容器内运行(并且您不应该使用 mvn spring-boot:run 插入容器来启动应用程序)。从我在这里看到的情况来看,您只是使用 docker 启动外部依赖项并在本地运行您的应用程序。
  • 当我使用mvn spring-boot:run 时,它不在容器内。我在我的电脑上本地运行它。我使用 Intellij 或终端构建项目。
  • 因此它不会工作,因为那些环境变量不存在。这些仅在 docker 内部可用。变量的名称是 sso-hostSSO_HOST,就像您声明它们一样(Spring BOot 有一些宽大处理,因此两者都应该工作)。

标签: maven spring-boot docker-compose environment-variables


【解决方案1】:

Spring 支持通过PlaceholderConfigurerSupport 在配置中提供默认值。默认值是: 之后的值。在你的情况下,你应该写:

client-id: ${OAUTH_CLIENTID:yourDevelopmentDefaultClientID}

如果您使用 @Value 注释来注入值,则您可以支持 SpEL 使用以下类型的表达式:#{someExpression} 用于更复杂的情况。

更新:

在您的情况下,我相信您正在颠倒变量的位置。正确的应该是:

key-set-uri: ${SSO_HOST:auth-server}/keys

这里是什么意思:首先,它会尝试使用SSO_HOST环境变量,这个环境变量是通过docker-compose提供给容器的。如果这个变量没有提供给进程,Spring 将使用auth-server 作为服务器的地址。在我看来,这个地址只在 docker-compose 网络中可见,所以如果你在这个网络之外运行你的应用程序,auth-server 地址将不可见。你知道认证服务器在哪里吗?它是另一个码头集装箱吗?它是在 localhost 上运行的吗?

一些有趣的参考:https://www.baeldung.com/spring-value-defaults

【讨论】:

  • 但是如何在key-set-uri: ${auth-server:${SSO_HOST}}/keys 中指定auth-serverSSO_HOST 的值呢?在 docker-compose 文件中指定了它们的值,但我似乎没有在项目中找到它们值的任何定义。是否使用-Dspring-boot.run.arguments= 运行这些参数是一个选项?
  • 我不确定变量的位置,但key-set-uri: ${auth-server:${SSO_HOST}}/keys 的顺序是在应该可以工作的项目版本中定义的。关于身份验证服务器。我认为它部署在云上的某个地方。如果我有 URL,我应该硬编码 application.yml 中的值吗?
  • 在我看来,要在 docker 之外运行应用程序,您应该硬编码服务器地址作为 SSO_HOST 环境变量的后备,提供:key-set-uri: ${SSO_HOST:<your remote address here>}。这样,如果 env 变量不存在,Spring 将使用您提供的地址。但是,请注意不要在源代码存储库中公开凭据。另一种选择(更安全)是在 .bash_rc 或 .profile 文件中提供 SSO_HOST 变量。 Spring 将在启动应用程序时加载它们。
  • 这实际上是我所做的。我将环境变量的值放在~/.profile 中,所以现在当我使用 Intellij 启动应用程序或在终端上运行mvn spring-boot:run 时会加载它们。
  • 良好且安全的解决方案!但是,在这种情况下,你必须改变位置,对吧?
【解决方案2】:

将 docker compose 中的环境变量作为对象而不是列表传递:

environment:
  RABBIT_HOST: rabbitstomp
  RABBIT_USER: guest
  RABBIT_PASS: user
  MONGO_HOST: mongodb://localhost:27017
  OAUTH_CLIENTID: nz-kek
  OAUTH_CLIENT_SECRET: DzXZxeOZOJHFZIUhObSpsne
  SSO_HOST: https://webweb.com
  CORS_HOSTS: HOST1,HOST2
  SES_HOST: ses
  SES_PORT: 6000
  REDIS_HOST: localhost
  REDIS_PORT: 6379` 

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2019-02-11
    • 2021-09-05
    • 2014-05-26
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多