Pass Docker arguments to Spring boot properties

Alex P. :

In a project locally that I've created to test passing Docker arguments to my spring boot application.properties I have in the application.properties: test.name=${name}

and in the application

@SpringBootApplication
public class RestServiceApplication {

    @Value("${test.name}")
    private String test;

    public static void main(String[] args) {
        SpringApplication.run(RestServiceApplication.class, args);
    }

    @Bean(name = "test")
    public String getTest() {
        return this.test;
    }
}

My Dockerfile:

FROM openjdk:8-jdk-alpine
ARG NAME
ENV TEST_NAME=${NAME}
RUN echo $TEST_NAME
ARG JAR_FILE=target/*.jar
RUN echo JAR_FILE
ADD ${JAR_FILE} app.jar
ENTRYPOINT ["java","-jar","/app.jar"]

Building it with sudo docker build -t gs-rest-service --build-arg NAME=Alex . This works fine locally

Now on a different project my application.properties:

bulk.api.username=${BULK_USERNAME}
bulk.api.password=${BULK_PASSWORD}

and my Dockerfile:

FROM maven:3.6.0-jdk-8 AS build

ARG ARTIFACTORY_USER
ARG ARTIFACTORY_PASSWORD

WORKDIR /build
COPY . .

RUN mvn -s settings.xml clean package

ARG BULK_USERNAME
ARG BULK_PASSWORD
ENV BULK_API_USERNAME=${BULK_USERNAME}
ENV BULK_API_PASSWORD=${BULK_PASSWORD}
RUN echo $BULK_API_PASSWORD

FROM openjdk:8-jre-alpine

WORKDIR /opt/cd-graph-import
COPY --from=build /build/target/abc-svc.jar .

ENTRYPOINT ["java", "-jar", "abc-svc.jar"]

My spring boot class:

@SpringBootApplication
public class SpringBootApplication {

    @Value("${bulk.api.username}")
    private String bulkApiUsername;

    @Value("${bulk.api.password}")
    private String bulkApiPassword;

    public static void main(String[] args) {
        SpringApplication.run(SpringBootApplication.class, args);
    }

    @Bean
    public RestTemplate restTemplate() {
        return new RestTemplateBuilder().basicAuthentication(bulkApiUsername, bulkApiPassword).build();
    }

    @Bean(name = "bulkApiUrl")
    public String getBulkApiUrl() {
        return this.bulkApiUrl;
    }
}

When this runs in gitlab with:

docker build -t $SERVICE_IMAGE --build-arg ARTIFACTORY_USER=$ARTIFACTORY_USER --build-arg ARTIFACTORY_PASSWORD=$ARTIFACTORY_PASSWORD --build-arg BULK_USERNAME=$BULKAPI_USERNAME --build-arg BULK_PASSWORD=$BULKAPI_PASSWORD .

I see that $BULK_API_PASSWORD is set properly but when running the application I get the error: `Error creating bean with name

'someApplication': Injection of autowired dependencies failed; nested exception is java.lang.IllegalArgumentException: Could not resolve placeholder 'BULK_USERNAME' in value "${BULK_USERNAME}"

What am I missing?

Maxim Popov :

According to spring boot application properties docs, you are able to set application properties by an environment variable. You should make env variable with the same name as a property name but if you use env variable, it's recommended to use '_' instead of '.'. For example if you want to set test.name you have to set TEST_NAME env argument.

In the first example, you set TEST_NAME env parameter in your docker file. When your application is starting, spring gets property from env variable (spring gets TEST_NAME, not NAME variable) and passes to the application, which replaces your default value "${name}". Please note here that spring not inject NAME variable, but replace property test.name by value from env variable.

In the second case, you haven't set BULK_API_USERNAME and BULK_API_PASSWORD env properties and spring doesn't replace default values and use ${API_USERNAME} and ${API_PASSWORD} as a properties value. You should set BULK_API_USERNAME and BULK_API_PASSWORD for passing your values to the app.

And also leave the value of properties in application.properties are empty. 'bulk.api.username=' and 'bulk.api.password='

Guess you like

Origin http://10.200.1.11:23101/article/api/json?id=397690&siteId=1