Reputation: 3171
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?
Upvotes: 3
Views: 4129
Reputation: 1227
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='
Upvotes: 4