Perfiles en Spring Boot: Ejecutá tu App en Cualquier Entorno


Al momento de ejecutar nuestra aplicación en diferentes entornos, usualmente nos encontramos en la situación de que las credenciales de las bases de datos cambian, o que las referencias a archivos ya no son validas, o bien que la manera de referenciar componentes en un entorno local no es la misma que en un entorno contenerizado… Por suerte para nosotros, Spring Boot permite crear perfiles y cambiar de forma muy simple entre diferentes configuraciones.
¿Qué son los perfiles?
En pocas palabras, los perfiles en Spring Boot son configuraciones etiquetadas que te permiten definir comportamientos o propiedades de la aplicación para diferentes entornos y seleccionarlas fácilmente al iniciar la aplicación.
¿Cuándo usar perfiles?
Situémonos en un hipotético caso de los desarrolladores de una aplicación simple llamada “Z“. Una vez que el equipo de desarrollo de Z desarrolló el sistema en un entorno local, se les pidió que armen los respectivos Dockerfiles de cada servicio y que prueben el sistema contenerizado para hacer pruebas mas integrales y dejarlo listo para desplegarlo en producción.
El equipo se encontró con que la base de datos que usaban para probar la aplicación en local, no tenia las mismas credenciales que la que usarían con la aplicación contenerizada. ¡Que problema!
El equipo de Z tiene las siguientes alternativas:
Reescribir las credenciales de las DB cada vez que cambien de entrono 🤢🤮
Desarrollar un perfil para cada entorno ⭐🤩✨✨
Sobrescribir las configuraciones en el docker-compose 🤢🤮
El equipo de Z se encuentra frente a un magnifico caso para usar perfiles.
Concepto
Los perfiles, permiten crear archivos de configuración segmentados por su nombre, por ejemplo, si la aplicación se ejecuta bajo un perfil llamado local, Spring va a buscar archivos de propiedades en el servicio con las siguientes nomenclaturas:
application**-local**.properties
application**-local**.yml (o .yaml)
Tambien, si se da el caso de poseer propiedades compartidas entre todos los perfiles, estas propiedades se pueden especificar en el application.properties o application.yml, que se ejecutara independientemente del perfil elegido…
De igual forma funciona con un Configuration Server, permitiendo una estructura como esta, por ejemplo, para un user-service:
config-repo/
├── application.yml # Propiedades comunes a todas las aplicaciones
├── application-prod.yml # Propiedades comunes al perfil `prod`
├── application-local.yml # Propiedades comunes al perfil `local`
├── user-service.yml # Propiedades específicas de `user-service`
├── user-service-prod.yml # Perfil `prod` para `user-service`
├── user-service-local.yml # Perfil `local` para `user-service`
Si se utilizara el perfil local en el user-service, en este caso, en el Configuration Server se ejecutarian:
application.yml
application-local.yml
user-service.yml
user-service-local.yml
De esta forma, mediante la externalizacion de configuraciones y su selección mediante perfiles, se origina una alternativa muy cómoda y modular, permitiendo un manejo simple de múltiples configuraciones.
Ejemplo Práctico
Retomando el caso de nuestra aplicación Z, su application.properties utilizado para el desarrollo de forma local se ve así:
spring.application.name=user-service
server.port=8090
spring.datasource.url=jdbc:postgresql://localhost:5432/users
spring.datasource.username=test
spring.datasource.password=test
spring.jpa.hibernate.ddl-auto=update
spring.jpa.properties.hibernate.dialect=org.hibernate.dialect.PostgreSQLDialect
Como se puede ver a simple vista, hay muchas cosas que a priori, no se deben llevar a un entorno que no sea de pruebas. Por este motivo, el equipo de Z, decide refactorizar el archivo para que contenga las propiedades que compartiran todos los perfiles. De esta forma, el application.properties pasa a verse de esta forma:
application.properties
spring.application.name=user-service
server.port=8090
spring.jpa.properties.hibernate.dialect=org.hibernate.dialect.PostgreSQLDialect
Una vez especificadas las propiedades que siempre estaran, independientemente de la eleccion del perfil, el equipo de Z, creo los siguientes archivos:
application-local.properties
spring.datasource.url=jdbc:postgresql://localhost:5432/users
spring.datasource.username=test
spring.datasource.password=test
spring.jpa.hibernate.ddl-auto=update
application-prod.properties
spring.datasource.url=jdbc:postgresql://userspostgres:5432/users
spring.datasource.username=supersecureusername
spring.datasource.password=ultrasecurepassword
spring.jpa.hibernate.ddl-auto=none
Ahora simplemente el equipo de Z cuando ejecute el servicio, por ejemplo con Maven en la consola, deberá especificar que perfil utilizar de la siguiente forma:
./mvnw spring-boot:run -DSPRING_PROFILES_ACTIVE=local
O bien, pueden ejecutar el servicio en docker agregando el parámetro antes especificado:
user-service:
build:
context: ./user-service
dockerfile: Dockerfile
environment:
- SPRING_PROFILES_ACTIVE=local
networks:
- prod-network
Conclusión
Los perfiles en Spring Boot son realmente versátiles. Para todas las dudas que tengas, la respuesta es muy probable que sea: Sí.
¿Puedo usar cualquier nombre para mis perfiles? Sí.
¿Puedo tener tantos perfiles como necesite? Sí.
¿Puedo utilizar mas de un perfil a la vez? Sí.
¿Puedo aplicar las mismas reglas de nomenclatura tanto en los servicios como en el Configuration Server? Sí.
¿Funcionan con configuraciones remotas? Sí.
¿Y con configuraciones locales? También sí.
Hay ciertos aspectos que no fueron cubiertos en este blog, como la agrupación de perfiles o la posibilidad de instanciar o no clases según el perfil utilizado. Para conocer como funcionan estos conceptos recomiendo leer la correspondiente documentacion.
En resumen, los perfiles en Spring Boot están diseñados para adaptarse a casi cualquier escenario de configuración, ya sea en entornos simples o sistemas complejos. Ahora ya sabes lo necesario para empezar a usar esta gran herramienta, mucha suerte!
Subscribe to my newsletter
Read articles from Tomas Darquier directly inside your inbox. Subscribe to the newsletter, and don't miss out.
Written by

Tomas Darquier
Tomas Darquier
I'm fascinated by how things work, which drives my interest in back-end development. Based in Argentina, I'm currently completing my bachelor's degree in Computer Science.