1

我想在我的项目中使用 Spring Native。目前在运行应用程序时,我在运行时传入环境变量。我需要在构建时将这些环境变量烘焙到图像中。

当我对环境变量进行硬编码时,Spring Native 可以正常工作,但我不想将它们提交到源代码控制中。我宁愿我的 CI 工具在构建时传递它们。

有没有人做到这一点?我还没有找到任何说明如何做到这一点的文档。

目前我的尝试都出错了:

构建.gradle


    plugins {
        id "java"
        id "org.springframework.boot" version "2.6.2"
        id 'io.spring.dependency-management' version '1.0.11.RELEASE'
        id "jacoco"
        id "org.flywaydb.flyway" version "7.11.2"
        id "com.github.ben-manes.versions" version "0.39.0"
        id 'org.springframework.experimental.aot' version '0.11.1'
    }
    
    group = 'org.api'
    
    repositories {
        mavenCentral()
        maven { url 'https://repo.spring.io/release' }
    }
    
    dependencies {
    
        // Spring Boot
        implementation('org.springframework.boot:spring-boot-starter-actuator')
        implementation('org.springframework.boot:spring-boot-starter-data-jpa')
        implementation('org.springframework.boot:spring-boot-starter-hateoas')
        implementation('org.springframework.boot:spring-boot-starter-web')
        implementation('org.springframework.boot:spring-boot-starter-security')
        implementation('org.springframework.boot:spring-boot-starter-aop')
        implementation('org.springframework.boot:spring-boot-starter-validation')
        runtimeOnly('org.springframework.boot:spring-boot-devtools')
        annotationProcessor "org.springframework.boot:spring-boot-configuration-processor"
    
        // Testing
        testImplementation(platform('org.junit:junit-bom:5.7.0'))
        testImplementation('org.junit.jupiter:junit-jupiter')
        testImplementation('org.springframework.boot:spring-boot-starter-test')
        testImplementation("org.assertj:assertj-core:3.21.0")
        testImplementation 'org.mockito:mockito-core:4.1.0'
        testImplementation "org.springframework.security:spring-security-test"
    
        // Persistence
        implementation('com.h2database:h2')
        implementation('org.postgresql:postgresql')
        implementation('org.springframework.boot:spring-boot-starter-jdbc')
        implementation "org.flywaydb:flyway-core:8.1.0"
    
        // Swagger
        implementation 'org.springdoc:springdoc-openapi-ui:1.5.12'
        implementation 'org.springdoc:springdoc-openapi-hateoas:1.5.12'
        implementation 'org.springdoc:springdoc-openapi-security:1.5.12'
    
        // Observability
        implementation 'io.sentry:sentry-spring-boot-starter:5.4.3'
        implementation 'io.sentry:sentry-logback:5.4.3'
    
        // Security
        implementation 'com.auth0:auth0-spring-security-api:1.4.1'
        implementation 'org.springframework.security:spring-security-oauth2-resource-server'
        implementation 'org.springframework.security:spring-security-oauth2-jose'
        implementation 'org.springframework.security:spring-security-config'
    
        // Outgoing Email
        implementation 'com.sendgrid:sendgrid-java:4.8.0'
    
        // Serialisation
        implementation 'com.fasterxml.jackson.core:jackson-databind:2.13.0'
    }
    
    sourceSets {
        test {
            resources {
                srcDir file('src/test/java')
                exclude '**/*.java'
            }
        }
    }
    
    test {
        useJUnitPlatform()
        testLogging {
            events "passed", "skipped", "failed"
        }
        systemProperty 'PORT', '8080'
        systemProperty 'SENTRY_DSN', 'https://123@456.ingest.sentry.io/789'
    }
    
    flyway {
        url = 'jdbc:postgresql://localhost:5432/api'
        user = 'postgres'
        password = 'mysecretpassword'
        schemas = ['public']
    }
    
    dependencyUpdates {
        outputFormatter = "html"
    }
    
    bootBuildImage {
        builder = "paketobuildpacks/builder:tiny"
        environment = [
                'BP_NATIVE_IMAGE' : 'true'
        ]
    }

设置.gradle

    pluginManagement {
        repositories {
            maven { url 'https://repo.spring.io/release' }
            gradlePluginPortal()
        }
    }
    
    rootProject.name = 'api'

应用程序.yml


    spring:
      hateoas.use-hal-as-default-json-media-type: false
      data:
        jpa:
          repositories:
            bootstrap-mode: deferred
      jpa:
        open-in-view: false
        properties:
          hibernate.jdbc.time_zone: UTC
        hibernate:
          ddl-auto: none
          naming:
            physical-strategy: org.springframework.boot.orm.jpa.hibernate.SpringPhysicalNamingStrategy
            implicit-strategy: org.springframework.boot.orm.jpa.hibernate.SpringImplicitNamingStrategy
      jmx:
        enabled: false
      security:
        oauth2:
          resourceserver:
            jwt:
              issuer-uri: https://localhost:9000
    
    auth0:
      audience: http://localhost:8080
    
    springdoc:
      packages-to-scan: org.api
      swagger-ui:
        path: /swagger-ui.html
        operationsSorter: method
        tagsSorter: alpha
        docExpansion: list
    
    management:
      endpoint:
        health:
          show-details: when_authorized
    
    server:
      port: ${PORT} <--- Environment Variable I need to pass in at build time
    
    sentry:
      dsn: ${SENTRY_DSN} <--- Environment Variable I need to pass in at build time
      max-breadcrumbs: 150
      logging:
        minimum-event-level: warn
        minimum-breadcrumb-level: info
      traces-sample-rate: 1.0
      in-app-includes: org.api

尝试编译使用: ./gradlew bootbuildimage -DSENTRY_DSN=https://123@456.ingest.sentry.io/789 -DPORT=8080

尝试将此添加到build.gradle

    bootBuildImage {
        builder = "paketobuildpacks/builder:tiny"
        environment = [
                'BP_NATIVE_IMAGE' : 'true',
                'SENTRY_DSN' : 'https://123@456.ingest.sentry.io/789',
                'PORT' : '8080'
        ]
    }

所有结果:


    > Task :generateAot
    2022-01-10 19:29:24.426  INFO 7749 --- [           main] o.s.a.build.ContextBootstrapContributor  : Detected application class: nz.ringfence.valuable.api.ValuableApiApplication
    2022-01-10 19:29:24.429  INFO 7749 --- [           main] o.s.a.build.ContextBootstrapContributor  : Processing application context
    org.springframework.beans.factory.BeanDefinitionStoreException: Failed to process import candidates for configuration class [nz.ringfence.valuable.api.ValuableApiApplication]; nested exception is java.lang.IllegalStateException: Error processing condition on io.sentry.spring.boot.SentryAutoConfiguration
            at org.springframework.context.annotation.ConfigurationClassParser.processImports(ConfigurationClassParser.java:610)
            at org.springframework.context.annotation.ConfigurationClassParser$DeferredImportSelectorGroupingHandler.lambda$processGroupImports$1(ConfigurationClassParser.java:812)
            at java.base/java.util.ArrayList.forEach(ArrayList.java:1511)
            at org.springframework.context.annotation.ConfigurationClassParser$DeferredImportSelectorGroupingHandler.processGroupImports(ConfigurationClassParser.java:809)
            at org.springframework.context.annotation.ConfigurationClassParser$DeferredImportSelectorHandler.process(ConfigurationClassParser.java:780)
            at org.springframework.context.annotation.ConfigurationClassParser.parse(ConfigurationClassParser.java:193)
            at org.springframework.context.annotation.ConfigurationClassPostProcessor.processConfigBeanDefinitions(ConfigurationClassPostProcessor.java:331)
            at org.springframework.context.annotation.ConfigurationClassPostProcessor.postProcessBeanDefinitionRegistry(ConfigurationClassPostProcessor.java:247)
            at org.springframework.context.support.PostProcessorRegistrationDelegate.invokeBeanDefinitionRegistryPostProcessors(PostProcessorRegistrationDelegate.java:311)
            at org.springframework.context.support.PostProcessorRegistrationDelegate.invokeBeanFactoryPostProcessors(PostProcessorRegistrationDelegate.java:112)
            at org.springframework.context.support.AbstractApplicationContext.invokeBeanFactoryPostProcessors(AbstractApplicationContext.java:746)
            at org.springframework.context.support.ApplicationContextAccessor.prepareContext(ApplicationContextAccessor.java:23)
            at org.springframework.context.annotation.BuildTimeBeanDefinitionsRegistrar.processBeanDefinitions(BuildTimeBeanDefinitionsRegistrar.java:66)
            at org.springframework.aot.context.bootstrap.generator.ApplicationContextAotProcessor.process(ApplicationContextAotProcessor.java:94)
            at org.springframework.aot.build.ContextBootstrapContributor.contribute(ContextBootstrapContributor.java:80)
            at org.springframework.aot.build.BootstrapCodeGenerator.generate(BootstrapCodeGenerator.java:91)
            at org.springframework.aot.build.BootstrapCodeGenerator.generate(BootstrapCodeGenerator.java:71)
            at org.springframework.aot.build.GenerateBootstrapCommand.call(GenerateBootstrapCommand.java:107)
            at org.springframework.aot.build.GenerateBootstrapCommand.call(GenerateBootstrapCommand.java:42)
            at picocli.CommandLine.executeUserObject(CommandLine.java:1953)
            at picocli.CommandLine.access$1300(CommandLine.java:145)
            at picocli.CommandLine$RunLast.executeUserObjectOfLastSubcommandWithSameParent(CommandLine.java:2352)
            at picocli.CommandLine$RunLast.handle(CommandLine.java:2346)
            at picocli.CommandLine$RunLast.handle(CommandLine.java:2311)
            at picocli.CommandLine$AbstractParseResultHandler.execute(CommandLine.java:2179)
            at picocli.CommandLine.execute(CommandLine.java:2078)
            at org.springframework.aot.build.GenerateBootstrapCommand.main(GenerateBootstrapCommand.java:112)
    Caused by: java.lang.IllegalStateException: Error processing condition on io.sentry.spring.boot.SentryAutoConfiguration
            at org.springframework.boot.autoconfigure.condition.SpringBootCondition.matches(SpringBootCondition.java:60)
            at org.springframework.context.annotation.ConditionEvaluator.evaluate(ConditionEvaluator.java:120)
            at org.springframework.context.annotation.ConditionEvaluator.shouldSkip(ConditionEvaluator.java:106)
            at org.springframework.context.annotation.ConditionEvaluator.shouldSkip(ConditionEvaluator.java:88)
            at org.springframework.context.annotation.ConfigurationClassParser.processConfigurationClass(ConfigurationClassParser.java:226)
            at org.springframework.context.annotation.ConfigurationClassParser.processImports(ConfigurationClassParser.java:600)
            ... 26 more
    Caused by: java.lang.IllegalArgumentException: Could not resolve placeholder 'SENTRY_DSN' in value "${SENTRY_DSN}"
            at org.springframework.util.PropertyPlaceholderHelper.parseStringValue(PropertyPlaceholderHelper.java:180)
            at org.springframework.util.PropertyPlaceholderHelper.replacePlaceholders(PropertyPlaceholderHelper.java:126)
            at org.springframework.core.env.AbstractPropertyResolver.doResolvePlaceholders(AbstractPropertyResolver.java:239)
            at org.springframework.core.env.AbstractPropertyResolver.resolveRequiredPlaceholders(AbstractPropertyResolver.java:210)
            at org.springframework.core.env.AbstractPropertyResolver.resolveNestedPlaceholders(AbstractPropertyResolver.java:230)
            at org.springframework.boot.context.properties.source.ConfigurationPropertySourcesPropertyResolver.getProperty(ConfigurationPropertySourcesPropertyResolver.java:79)
            at org.springframework.boot.context.properties.source.ConfigurationPropertySourcesPropertyResolver.getProperty(ConfigurationPropertySourcesPropertyResolver.java:60)
            at org.springframework.core.env.AbstractEnvironment.getProperty(AbstractEnvironment.java:594)
            at org.springframework.boot.autoconfigure.condition.OnPropertyCondition$Spec.collectProperties(OnPropertyCondition.java:140)
            at org.springframework.boot.autoconfigure.condition.OnPropertyCondition$Spec.access$000(OnPropertyCondition.java:105)
            at org.springframework.boot.autoconfigure.condition.OnPropertyCondition.determineOutcome(OnPropertyCondition.java:91)
            at org.springframework.boot.autoconfigure.condition.OnPropertyCondition.getMatchOutcome(OnPropertyCondition.java:55)
            at org.springframework.boot.autoconfigure.condition.SpringBootCondition.matches(SpringBootCondition.java:47)
            ... 31 more
    
    > Task :generateAot FAILED
    
    FAILURE: Build failed with an exception.

4

0 回答 0