Maximize Page
Tech & DevOps HubEspace Tech & DevOps: Explorez le monde du Dev, du Cloud et des outils DevOps à travers nos articles et discussions Explore the world of development, the cloud and DevOps tools

Les Profils Spring: Préparation au multi-branches

Date de l'article:18-10-2025
Github-Actions Spring Boot
Mise en place de trois profils Spring Boot distincts (dev, staging, prod) avec une configuration de base de données adaptée à chaque environnement. Préparation de l'application à la stratégie multi-branches du pipeline CI/CD avec les principes Gitlab flow

Cet article présente la mise en place des profils Spring, la configuration des bases de données et des jeux de données associés, ainsi que la gestion des configurations par environnement et l'adaptation des paramètres pour les tests unitaires et d'intégration.

Pourquoi utiliser des profils Spring Boot ?
Chaque environnement ayant des besoins spécifiques, il nous faut adapter l'application à son contexte, par exemple en utilisant une base de données embarquée en développement et une base externe en production. L'idée est d'éviter d'avoir une seule configuration globale qui risque d'effacer des données ou d'exposer des informations sensibles
Définition de la base de données selon le profil, la branche et les besoins de l'environnement:
Profil Branche Objectif / Besoin Type de DB Port Caractéristiques
dev develop Développement local locale 8080 ddl-auto=create-drop - spring.sql.init.mode=always
Les données sont recréée à chaque lancement de l'application, les logs sont détaillés
staging staging Préproduction / tests persistante (VM/Docker) 8081 ddl-auto=update - spring.sql.init.mode=never
Base persistante: les données sont conservées (init manuelle), logs modérés, proche de la prod
prod main Production finale distante (prod/CI) 8080 ddl-auto=update - spring.sql.init.mode=never
Base stable; les données ne jamais modifiées automatiquement, logs limités, sécurité et performance

En entreprise, la base de staging est souvent une copie anonymisée de la base de production pour tester en conditions réelles.


Structure typique des fichiers de configuration

Dans le projet Spring Boot, nous configurons ces besoins dans le répertoire "src/main/resources"
Chaque environnement dispose de sa propre branche git, et chaque branche à des besoins spécifiques

Tous les fichiers sont présents dans toutes les branches
Le fichier application.properties est la configuration commune à tous les environnements:
  • Il est utilisé pour la gestion centralisée de la configuration, comme paramétrer la base de données, le port, les healthcheck, etc
  • Il contient des paires clé=valeur pour configurer l'application, permettant de modifier son comportement sans toucher au code
  • Il facilite la modification des paramètres par défaut de Spring Boot et offre une grande flexibilité pour les différents environnements
  • Il est surchargé par les fichiers de profiles
Les fichiers de profils:
Ils sont essentiels pour gérer des configurations différentes selon l'environnement, en activant ou désactivant des propriétés et des composants spécifiques, ce qui offre flexibilité, maintenabilité et déploiement simplifié sans modifier le code principal
  • application-dev.properties: config locale et pour dev
  • application-staging.properties: utilisé seulement en staging
  • application-prod.properties: utilisé en production
Le code et les fichiers de configuration restent identiques entre les branches;
Seules les valeurs externes, injectés par le pipeline (secrets, URLs de serveurs) varient d'un environnement à l'autre
     application-{profile}.properties ou les variables d'environnement. Des valeurs par défaut sont prévues uniquement pour le développement local.

Configuration des fichiers suivant les besoins des profils
Structure des fichiers
FLASHCARDS/
├── src/main/resources/
│   ├─ application.properties
│   ├─ application-dev.properties
│   ├─ application-staging.properties
│   └─ application-prod.properties

Fichiers de données sql, par branche
FLASHCARDS/
├── src/main/resources/db/dev/init-data.sql   ← données de develop
├── db/prod/init-data.sql                     ← données de prod
└── db/staging/init-data.sql                  ← données de staging
En dev: Les données sont auto-loadé à chaque démarrage de l'application
En staging / [prod]: Insérer les données manuellement depuis la commande: psql -h [host] -U postgres -d flashcardsdb -f db/[profile]/init-data.sql
Le mot de passe se trouve dans src/main/resources/application.properties

Le fichier application.properties
spring.application.name=flashcards
spring.jpa.open-in-view=false
spring.jpa.show-sql=false

spring.profiles.default=dev

→ Contient le profil "dev" par défaut, ce qui empêche l'application de démarrer sans configuration explicite, réduisant ainsi les risques d'erreurs et offrant une configuration de base
# PostgreSQL (all)
spring.datasource.url=jdbc:postgresql://${DB_HOST:localhost}:${DB_PORT:5432}/flashcardsdb
spring.datasource.username=${DB_USER:postgres}
spring.datasource.password=${DB_PASSWORD:pswd}
spring.datasource.driver-class-name=org.postgresql.Driver

→ Le profil s'active automatiquement si aucun autre profil n'est spécifié lors du lancement de l'application

→ Logs attendus:
No active profile set, falling back to 1 default profile: "dev"
Points clés :
→ La configuration est complétée par les fichiers de profil comme "application-{profil}.properties" pour les configurations distinctes
→ Les avantages sont le découplage, qui sépare la configuration de la logique métier
Normalement on ne configure pas la base de données dans le fichier commun, mais bien dans les fichiers de profils
Ma décision de la mettre là est uniquement pour éviter la duplication (projet démo).
En temps normal: 1 base de données + credentials différent par branche/environnement!

1. Le profil dev (développement local)
Le fichier "application-dev.properties"
spring.jpa.hibernate.ddl-auto=create-drop
spring.jpa.show-sql=true
spring.jpa.properties.hibernate.format_sql=true

spring.sql.init.mode=always
spring.sql.init.data-locations=classpath:db/dev/init-data.sql
spring.jpa.defer-datasource-initialization=true

# log level
logging.level.org.springframework.security=INFO

# default port
server.port=8080

Objectif:
Faciliter les tests rapides, les rechargements de données, et les logs détaillés. Comportements:
→ La base est créée, puis supprimée à l'arrêt
→ Il charge le script init-data.sql à chaque lancement de l'application
→ Les logs SQL activés et configurables selon le niveau nécessaire:
     INFO WARN DEBUG

2. Le profil staging: pré-production / environnement de test
Le fichier application-staging.properties
# Hibernate: do not destroy anything
spring.jpa.hibernate.ddl-auto=update
spring.jpa.show-sql=false
spring.sql.init.mode=never

# Different port
server.port=8081
Objectif: Simuler la production, avec une base stable et des tests de charge
Comportements:
→ Met à jour le schéma sans supprimer les données
→ Pas de rechargement automatique de la table
→ Pas de log SQL
→ Port différent, pour faire tourner [develop] et [staging] côte à côte
→ Idéal pour les tests de performance et/ou via Postman/Newman

[Staging] / [prod]: Changer de profil au démarrage

Pour utiliser le profil staging ou prod alors que le profil dev est le profil par défaut, il faut écraser la configuration au moment du démarrage

Utilisez une variable d'environnement (Recommandé):
export SPRING_PROFILES_ACTIVE=staging
./mvnw spring-boot:run
ou le profil ou le fichier jar:
./mvnw spring-boot:run -Dspring-boot.run.profiles=prod
#ou encore
java -jar target/flashcards-1.1.0.jar --spring.profiles.active=prod

[Staging] / [prod] : Pas d'initialisation de données au démarrage
→ Pas de rechargement automatique de la table: Il faut l'initialiser une première x avant de lancer l'application
→ Insérer les données manuellement depuis la commande: psql -h [host] -U postgres -d flashcardsdb -f db/{profile}/init-data.sql
→ Vous pouvez redéfinir le user et mot de passe (voir le readme) ou, utiliser ceux définis dans src/main/resources/application.properties

3. Le profil prod (production)
Le fichier "application-prod.properties"
# Prod safe
spring.sql.init.mode=never
spring.jpa.hibernate.ddl-auto=update
spring.jpa.show-sql=false

server.port=${PORT:8080}
Objectif : Stabilité, sécurité et performance
Points clés : → Pas de logs SQL
→ Il à été de mon choix d'utiliser spring.jpa.hibernate.ddl-auto=update au lieu de validate pour avoir (éventuellement) des données à disposition au démarrage.

Bonnes pratiques
  • Toujours séparer les profils: Ne jamais activer dev en production
  • Protéger les credentials: Utiliser les secrets GitHub,.env, ou Docker secrets
  • Base staging = clone anonymisé de la prod. Permet des tests réalistes sans risques
  • Tests automatisés par environnement. Chaque branche déclenche son propre workflow CI/CD

Les profils de tests
FLASHCARDS/
├── src/
│   └─ test/java/com/example/flashcards/
│       ├─ controller/                    ← test unitaire
│       ├─ dto/
│       ├─ entity/                        ← test unitaire
│       ├─ integration/                   ← test it 
│       ├─ mapper/
│       ├─ service/
│       └─ resources/
│           ├─ application-it.properties    ← it profile
│           └─ application-test.properties  ← test profile 

Ces profils sont utilisés exclusivement par les test et sont localisés dans: "src/test/resources/"

Grâce aux annotations, les profils trouvent les tests et leurs configuration;
  • profile-test.application pour les tests unitaires
  • profile-it.application pour les tests d'intégration
Ils tournent dans toutes les branches et vérifies le bon état du code

Le profil "test"
Le fichier application-test.properties
spring.datasource.url=jdbc:h2:mem:testdb;DB_CLOSE_DELAY=-1
spring.datasource.driverClassName=org.h2.Driver
spring.datasource.username=sa
spring.datasource.password=

spring.jpa.database-platform=org.hibernate.dialect.H2Dialect
spring.jpa.hibernate.ddl-auto=create-drop
spring.jpa.show-sql=true

spring.sql.init.mode=never
spring.liquibase.enabled=false
spring.flyway.enabled=false

Utilise une base éphémère au lieu de Postgres
Logs attendus:
[INFO] -------------------------------------------------------
[INFO]  T E S T S
[INFO] -------------------------------------------------------
      :: Spring Boot ::                (v3.5.4)

      //... main] c.e.f.i.CategoryControllerTest  
              : The following 1 profile is active: "test"


Le profil "it"
Le fichier application-it.properties
# IT Behavior
spring.jpa.hibernate.ddl-auto=create-drop
spring.jpa.show-sql=false

# Migrations
spring.liquibase.enabled=false
spring.flyway.enabled=false

spring.sql.init.mode=never

Dans la CI, il est configuré à minima, pour être utilisé par H2 en local et, par Postgres (suivant l'environnement)

Logs attendus:
[INFO]  T E S T S
[INFO] -------------------------------------------------------
      :: Spring Boot ::                (v3.5.4)
      //... main] c.e.f.i.CategoryIntegrationIT  
                    : The following 1 profile is active: "it"

Différence fondamentale entre les applis Java/Spring Boot (où les profils sont intégrés au framework) et des environnements comme PHP, où la gestion des environnements est plus manuelle et basée sur des configurations distinctes, de variables d'environnements et de branches de déploiements séparés plutôt que sur des profils logiques. Cela offre la même souplesse que Spring Boot, mais avec un peu plus de gestion manuelle.

Dans l'article suivant, nous passerons à la création de la branche develop, où nous mettrons en place tout les éléments nécessaire à la CI de base

Laissez-moi un commentaire

En postant un commentaire anonyme, vous adhérez automatiquement aux conditions d'utilisation du site.