I have a Spring application that I have to deploy in production. Unfortunately I am unable to turn the prod profile on. I have an application-dev.yml and application-prod.yml file as well as application.yml.
My application.yml is as follows:
# ===================================================================
# Spring Boot configuration.
#
# This configuration will be overridden by the Spring profile you use,
# for example application-dev.yml if you use the "dev" profile.
#
# More information on profiles: http://www.jhipster.tech/profiles/
# More information on configuration properties: http://www.jhipster.tech/common-application-properties/
# ===================================================================
# ===================================================================
# Standard Spring Boot properties.
# Full reference is available at:
# http://docs.spring.io/spring-boot/docs/current/reference/html/common-application-properties.html
# ===================================================================
eureka:
client:
enabled: true
healthcheck:
enabled: true
fetch-registry: true
register-with-eureka: true
instance-info-replication-interval-seconds: 10
registry-fetch-interval-seconds: 10
instance:
appname: majurca
instanceId: majurca:${spring.application.instance-id:${random.value}}
lease-renewal-interval-in-seconds: 5
lease-expiration-duration-in-seconds: 10
status-page-url-path: ${management.context-path}/info
health-check-url-path: ${management.context-path}/health
metadata-map:
zone: primary # This is needed for the load balancer
profile: ${spring.profiles.active}
version: ${info.project.version}
ribbon:
eureka:
enabled: true
management:
security:
roles: ADMIN
context-path: /management
info:
git:
mode: full
health:
mail:
enabled: false # When using the MailService, configure an SMTP server and set this to true
spring:
profiles:
default: prod
active: prod
application:
name: majurca
jackson:
serialization.write_dates_as_timestamps: false
jpa:
open-in-view: false
hibernate:
ddl-auto: none
naming:
physical-strategy: org.springframework.boot.orm.jpa.hibernate.SpringPhysicalNamingStrategy
implicit-strategy: org.springframework.boot.orm.jpa.hibernate.SpringImplicitNamingStrategy
messages:
basename: i18n/messages
mvc:
favicon:
enabled: false
thymeleaf:
mode: XHTML
security:
basic:
enabled: false
server:
session:
cookie:
http-only: true
info:
project:
version: #project.version#
# ===================================================================
# JHipster specific properties
#
# Full reference is available at: http://www.jhipster.tech/common-application-properties/
# ===================================================================
jhipster:
async:
core-pool-size: 2
max-pool-size: 50
queue-capacity: 10000
# By default CORS is disabled. Uncomment to enable.
#cors:
#allowed-origins: "*"
#allowed-methods: "*"
#allowed-headers: "*"
#exposed-headers: "Authorization,Link,X-Total-Count"
#allow-credentials: true
#max-age: 1800
mail:
from: majurca#localhost
swagger:
default-include-pattern: /api/.*
title: majurca API
description: majurca API documentation
version: 0.0.1
terms-of-service-url:
contact-name:
contact-url:
contact-email:
license:
license-url:
ribbon:
display-on-active-profiles: dev
# ===================================================================
# Application specific properties
# Add your own application properties here, see the ApplicationProperties class
# to have type-safe configuration, like in the JHipsterProperties above
#
# More documentation is available at:
# http://www.jhipster.tech/common-application-properties/
# ===================================================================
application:
forms:
register:
autocomplete-cp-nbitems: 20
google:
recaptcha:
url: https://www.google.com/recaptcha/api/siteverify
secret: 6Lci63UUAAAAAIsluk6G3ueNiJ_ET0m4luMsC8O5
key: 6Lci63UUAAAAADFyeZFTkEaHshVK2LQgYV63PPD_
#key: 6LfUG3UUAAAAAMxScj7ZFY-OXedoWLRzl0wryrrF
#secret: 6LfUG3UUAAAAANsSIsCFOi3X9uYzS72De8EqKqNM
So you can see I have spring.profiles.default and spring.pofiles.active set to prod. I also tried to build the app with maven and the option -Dspring.profiles.active=prod but despite this each time I run the war generated it says The following profiles are active: swagger,dev.
Anyone has a idea why the prod profile is not loaded ? Thanks in advance.
I've verified on spring-boot 2.1.4 the following configurations:
application.yaml:
spring:
profiles:
active: dev
application-dev.yaml:
sample:
value: development
application-prod.yaml:
sample:
value: production
And the following (very simple) spring boot application:
package com.example.demo;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.context.event.ApplicationStartedEvent;
import org.springframework.context.event.EventListener;
#SpringBootApplication
public class DemoApplication {
#Value("${sample.value}")
private String sampleValue;
public static void main(String[] args) {
SpringApplication.run(DemoApplication.class, args);
}
#EventListener
public void onAppStarted(ApplicationStartedEvent evt) {
System.out.println("Sample Value: " + sampleValue);
}
}
This configuration works, even if I don't supply any flags: java -jar myapp.jar
So there must be something else here, related to your code.
Its hard to say whats wrong without seeing the application, however I did found one "suspicious" statement:
You say, that no matter what you try:
The following profiles are active: swagger,dev
Now where does the 'swagger' profile come from? I don't see any reference to it. If you run the application with java -jar myapp.jar one possibility I can see is that there is somewhere spring.factories file that defines an EnvironmentPostProcessor - its a hook where you can "fiddle" with profiles and, among other things add active profiles "manually" (in code).
So please check this possibility, but again - what you've done is correct in spring boot (well, technically you don't need spring.profiles.default entry but it doesn't harm)
Spring Boot can load the same properties from many locations , which you can refer its loading order in the docs at here.
The upper part in the list have a higher loading priority than the lower part.That means what you define in the application-xxx.yml can be overridden by the same properties that are also defined in the OS env variable or JVM properties or etc .....
As the command line arguments has a pretty high loading order , which means basically you can try to use it to set the profile by adding --spring.profiles.active=prod to the command that start the application such as :
$ java -jar myproject.jar --spring.profiles.active=prod
Related
I have a spring cloud config client and server. I have added some logging-logback settings in the application.yaml of client and I have a different setting under config server. I see that the settings from server are never picked. Can somebody please help. I tried with different versions of spring boot and cloud but observe the same behaviour everywhere.
Please note, I only have issues with the logback.rollingpolicy.max-file-size
All other properties are picked from config-server
My application.yaml in the client
logging:
level:
root: info
file:
path: /Users/abc/demo/src/main/resources/logs
name: application
logback:
rollingpolicy:
max-file-size: 1MB
My bootstrap.yaml
spring:
cloud:
config:
enabled: true
uri: http://localhost:8402
application:
name: demo
My demo.yaml in cloud config server
logging:
level:
root: info
file:
path: /Users/abc/demo/src/main/resources/logs
name: demo
logback:
rollingpolicy:
max-file-size: 500KB
How to use application.yml in spring cloud config client application?
spring:
application:
name: app-cli
profiles:
active: DEV
config:
import: "configserver:"
cloud:
config:
name: ${spring.application.name}
uri: http://192.168.0.12:8888
username: thirumal
password: thirumal
request-read-timeout: 200
request-connect-timeout: 100
fail-fast: true
The client app is configure with all the required properties, still it's not connecting to config-server.
The lib implementation 'org.springframework.cloud:spring-cloud-starter-config'
I'm setting an environment variable inside my docker-compose.yaml file and want to use that variable's value inside my Spring Boot's application.yaml. I was told that doing something like
app:
auth:
tokenSecret: tokensecretvaluehere
tokenExpirationMsec: 864000000
oauth2:
sso:
url: ${SSO_URL}
(where SSO_URL is defined in my docker-compose.yaml) in my Spring application.yaml. However, this causes an error when I run docker-compose up --build because it can't find that variable (error is like: Could not resolve placeholder SSO_URL in value "${SSO_URL}"). This is an example of what my docker-compose.yaml:
api:
restart: always
ports:
- "8080:8080"
links:
- redis
- db
environment:
- SERVER_SERVLET_SESSION_COOKIE_DOMAIN=localhost
- SSO_URL=myvaluehere
I was asked to not uses the System.getenv functions in Java and instead set the variable like above. From there I would just use the #Value annotation to get it in my Java code as like below:
#Value("${app.oauth2.sso.url}")
private String ssoUrl;
This is more of the application.yaml:
heb:
togglr:
jwt:
secret:
id: 101
session:
seconds: 600
tokenheader: X-TOGGLR-TOKEN
logging:
level:
com:
heb: debug
default: debug
path: logs
server:
error:
whitelabel:
enabled: false
port: 8080
servlet:
context-path: /togglr-api
use-forward-headers: true
spring:
application:
name: togglr_api
freemarker:
enabled: false
groovy:
template:
enabled: false
jmx:
enabled: false
main:
banner-mode: 'off'
thymeleaf:
cache: false
security:
oauth2:
client:
registration:
github:
clientId:
clientSecret:
redirectUri:
scope:
- user:email
- read:user
app:
auth:
tokenSecret:
tokenExpirationMsec: 864000000
oauth2:
sso:
url: ${SSO_URL}
In general spring boot applications are able to read the Environment variables accessible in the docker container. Its stated in the documentation (see item 10 in the list at the very beginning of the document).
So the problem might be elsewhere:
It might be a typo in the question, but if you're using application.yaml as opposed to application properties, then you should have something like:
sso:
url: ${SSO_URL}
Make sure, that the env variable SSO_URL is indeed accessible in the container even before you start the spring boot application. In java (for debugging purposes only) you can do something like:
#SpringBootApplication
public class MyApp {
public static void main(String [] args) {
System.out.println(System.getenv("SSO_URL"));
SpringApplication.run(MyApp.class);
}
}
Solution was to not use an underscore character in the variable name.
I feel what you are missing is the build context within the docker-compose file. Or, you have multiple profile based application.yml and not the correct profile is being set.
Below is the working code / config. So we are creating a springboot application from docker-compose, where docker-compose builds the image of springboot application and passes the required environment variables.
Snippet from Spring application.yml where we are using the env variable named API_BASE and TEST_API_PATH
third-party-api:
base-url: ${API_BASE}
test-api-path: ${TEST_API_PATH}
Below is the snippet from docker-compose.yml
my-app:
image: my-app-image-name
build:
dockerfile: Dockerfile
context: .
ports:
- '9080:8080'
environment:
API_BASE: http://mock-api:8080
TEST_API_PATH: /someTestApiPath
SPRING_PROFILES_ACTIVE: dev
Docker file of my application is pretty simple.
FROM openjdk:17-alpine
ARG JAR_FILE=build/libs/*.jar
COPY ${JAR_FILE} app.jar
ENTRYPOINT ["java","-jar","/app.jar"]
Dockerfile and docker-compose.yml are on the same hierarcy, if there is any difference in your structure then it should reflect in below config of docker-compose.yml
build:
dockerfile: Dockerfile
Is there anyway to make spring cloud config client's application.yml read values from spring config server?
For example,
on my spring cloud config client, the application.yml is like this
spring:
application:
name: clienttest
mvc:
view:
prefix: /jsp/
suffix: .jsp
server:
port: 8080
context-path: /clienttest
tomcat:
uri-encoding: UTF-8
eureka:
client:
service-url: {"defaultZone":"http://dev.euraka01.app.com:8769/eureka/,http://dev.euraka02.app.com:8770/eureka/"}
instance:
prefer-ip-address: true
and my bootstrap.yml file is as below
spring:
application:
name: clienttest
cloud:
config:
name: clienttest
uri: http://192.168.2.101:9000
enabled: true
profile: out_test
label: master
now for the service-url value, for different environment, I have to config different eureka url values, my question is that, is there anyway that I can config the service-url value in the config server? like I set the value as ${service-url} in the application.yml, and when I start the config client server, it get the value from the config server according the profile and label which I set in the bootstrap.yml.
You can look up properties on the config server by both profile and label, where label is either either a branch, tag.
/{application}/{profile}[/{label}]
/{application}-{profile}.yml
/{label}/{application}-{profile}.yml
/{application}-{profile}.properties
/{label}/{application}-{profile}.properties
In your example above your config server will try and find a file named
clienttest-out_test.properties
In the git repo on the master branch.
spring:
application:
name: clienttest
cloud:
config:
profile: out_test
label: master
See the example and also a good doc here
Essex Boy,
Thank you very much for your help, and I was able to read the value from different config profile before.
My question is how to make application.yml get the value from config server, and now I've solve it by myself, the answer is quite easy, in the application, set value like ${service-url}, the full answer is as below:
in my application.yml, the content is as below:
spring:
application:
name: clienttest
server:
port: 8080
context-path: /clienttest
tomcat:
uri-encoding: UTF-8
eureka:
client:
service-url: {"defaultZone":"${service-url}"}
instance:
prefer-ip-address: true
Please note the service-url value, now the value is set as {"defaultZone":"${service-url}"}, and in my application.properties file which on the config server, the properties file content is as below:
service-url=http://192.168.2.101:8769/eureka/,http://192.168.2.101:8770/eureka/
then when I start the mocroservice, it could resist it self on the http://192.168.2.101:8769/eureka/ and http://192.168.2.101:8770/eureka/
which is what result I want.
I have configured a Spring Cloud Config server to force BASIC authentication and here is my application.yml file:
# Config Repo:
spring:
cloud:
config:
server:
git:
uri: file:///${HOME}/microservices_config_repo
# Show sensitive information for endpoints:
endpoints:
sensitive: true
# Security for endpoints:
management:
security:
enabled: true
security:
user:
name: user1
password: changeme
My issue I am having is that when I start the server up as:
mvn spring-boot:run
The server endpoints FORCE BASIC Authentication.
But when I start the Application.main() method, BASIC Authentication is enabled, but NOT enforced.
Meaning I can access configuration on:
http://localhost:8888/client-config
and
http://user1:changeme#localhost:8888/client-config
Can anyone help me understand why this is occuring and how to enforce BASIC Authentication while running the Application.main(), and not just through the Maven spring-boot plugin?
Note, when I use maven to package the app into a jar, then run the generated jar, BASIC Authentication is enforced, but still not through the IDE running just the Application.main directly.
Maybe the format the oy Yaml for example to me seems works like this:
server:
port:9999
spring:
application:
name: config-server-sample
cloud:
config:
name: ${spring.application.name}
fail-fast: true
server:
git:
uri: url
username: xx
password: zz
default-label: master
basedir: '${user.home}/${spring.application.name}/default'
timeout: 10
clone-on-start: true
force-pull: true
security:
basic:
enabled: true
path: /**
ignored: /health**,/info**,/metrics**,/trace**
user:
name: admin
password: tupassword