Spring Boot profiles

Como desplegar una aplicación Spring Boot + Angular en un servidor cloud VPS

Las aplicaciones raramente se utilizan en único entorno, como mínimo lo normal es tener entornos para desarrollo, qa, preproducción, producción, … y muy probablemente cada entorno va a tener sus particularidades como por ejemplo la base de datos, que en desarrollo podría ser una base de datos en memoria y en cada uno de los otros entornos los parámetros de conexión serán distintos, por lo que vamos a necesitar mantener varias configuraciones distintas y los perfiles de Spring Boot nos ayudan a hacerlo.

Como siempre vamos a partir del proyecto del tutorial de spring boot para añadirle esta característica para poder desplegarlo en distintos entornos.

¿Cómo se crean los perfiles en Spring Boot?

Si utilizamos archivos de propiedades .properties tenemos que añadirle el sufijo con el nombre del profile al nombre del properties, por ejemplo application.properties, application-dev.properties, application-prod.properties, … pero si usamos .yml como en nuestro caso aunque también podemos hacerlo así también tenemos la posibilidad de definirlos todos en el mismo archivo.

Por lo tanto si queremos definir un perfil para desarrollo y otro para producción nuestro archivo de propiedades se convertiría en algo como esto:


server:
  port: 9876
  servlet:
    context-path: /miapp

spring:
  profiles:
    active: dev
  datasource:
    driver-class-name: com.mysql.jdbc.Driver
  jpa:
    database-platform: org.hibernate.dialect.MySQL57Dialect
    hibernate:
      ddl-auto: create-drop
  messages:
    basename: i18n/messages
    encoding: UTF-8
      
logging:
  level:
    org:
      hibernate:
        SQL: debug
        
---

spring:
  profiles: dev
  datasource:
    url: jdbc:mysql://localhost:8889/pruebas?useSSL=false
    username: root
    password: root
      
---

spring:
  profiles: prod
  datasource:
    url: jdbc:mysql://10.20.30.40:3306/pruebas
    username: user
    password: Mipassword1+

En la primera parte tenemos todas las propiedades que son comunes a todos los entornos y separados por --- tenemos cada uno de los perfiles que queremos definir solo con las propiedades distintas para que sea más sencillo de mantener. En este caso el perfil no se puede sacar del nombre del archivo y por eso lo tenemos que indicar con spring: profiles: nombre.

Tanto si usamos uno como varios archivos de configuración hay que definir en el general el perfil que estará activo cuando no se indique uno de otro modo con spring: profiles: active: nombre

Y con esto ya podemos ejecutar la aplicación pasándole -Dspring.profiles.active=dev cuando ejecutemos la aplicación con el perfil que queremos ejecutar aunque quizás no sea la mejor forma de asegurarse de que se esta ejecutando con el perfil correspondiente al entorno correspondiente.

Seleccionar el perfil de Spring Boot con una variable de entorno

Una buena opción es utilizar una variable de entorno para elegir el profile de Spring Boot que queremos que se ejecute y lo podemos hacer directamente en el archivo de configuración con lo que nos quitamos de pasar los parámetros al arrancarlo y nos aseguramos que siempre se ejecutará la configuración del entorno que corresponde. Para utilizar variables de entorno desde el .yml hay que poner la variable entre ${}, la variable de entorno se la pasamos donde indicamos cual es el perfil que esta activo.


spring:
  profiles:
    active: ${miVariableDeEntornoPerfil}

Vincular los perfiles de Maven y de Spring Boot

Otra opción interesante es usar el perfil seleccionado en Maven para utilizarlo también en Spring, la forma de hacerlo es muy similar a usar las variables de entorno pero en este caso el delimitador es @...@, por lo tanto quedaría así.


spring:
  profiles:
    active: @appProfile@

También le podemos añadir '' si el IDE nos dice que no le gusta, o cambiar los delimitadores en el pom.xml añadiendo
<resource.delimiter>#{*}</resource.delimiter> dentro de properties si queremos usar nuestra propiedad como #{appProfile} por ejemplo (si el carácter de inicio y cierre es el mismo solo hay que poner ese carácter una vez <resource.delimiter>@</resource.delimiter>).


spring:
  profiles:
    active: '@appProfile@'

Y por supuesto tenemos que definir la variable en cuestión en los perfiles de maven para que se pueda utilizar.


<profiles>
  <profile>
    <id>dev</id>
    <properties>
      <appProfile>dev</appProfile>
    </properties>
    <activation>
      <activeByDefault>true</activeByDefault>
    </activation>
  </profile>
  <profile>
    <id>prod</id>
    <properties>
      <appProfile>prod</appProfile>
    </properties>
  </profile>
</profiles>

De este modo cuando ejecutemos una tarea Maven y le indiquemos un perfil automáticamente este perfil también se va a utilizar en Spring Boot, por ejemplo si hacemos un mvn package -Pprod vamos a generar la aplicación con la configuración de producción y la ejecutemos donde la ejecutemos va a tener esa configuración.

Como siempre todo lo que hemos visto aquí está incorporado en el proyecto que puedes revisar en github.