Configuration externalisée

La configuration de Tomcat est centralisée dans le fichier server.xml. Ce fichier est relativement simple à comprendre et à modifier, ce qui le rend adapté à des configurations classiques. En revanche, cette approche devient moins pratique dans des environnements modernes ou dynamiques, en particulier dans le cloud, où la configuration doit souvent être externalisée.

Lecture de la configuration

Au démarrage de Tomcat, le fichier server.xml est lu et interprété par le composant interne appelé digester. Ce dernier est chargé de parser les fichiers XML de configuration et de construire les objets Java correspondants.

Le digester offre une fonctionnalité de substitution de placeholders. Ceux-ci sont remplacés par des valeurs issues de différentes sources de propriétés, ce qui permet de rendre la configuration plus flexible et adaptable à l’environnement d’exécution.

Par défaut, les placeholders sont remplacés par des system properties.

Propriétés système

Un placeholder est défini à l’aide de la syntaxe ${key} ou ${key:-default-value}. Si la propriété n’est pas définie, la valeur par défaut est utilisée.

Dans l’exemple ci-dessous, on déclare une datasource dans server.xml, avec la possibilité de définir ses attributs principaux dans des propriétés système.

<Resource name="jdbc/my-global-ds"
          type="javax.sql.DataSource" auth="Container"
          driverClassName="org.database.Driver"
          url="${datasource.url:-jdbc:derby://localhost:1527/sewadb}"
          username="${datasource.username:-sa}"
          password="${datasource.password:-sapwd}" />

Les propriétés peuvent être définies comme propriétés système au démarrage de Tomcat, par exemple via le script setenv.sh :

# setenv.sh
CATALINA_OPTS="-Ddatasource.url=jdbc:database://server:1234/schema \
               -Ddatasource.username=dbusername \
               -Ddatasource.password=dbpassword"

Il est également possible de les définir dans le fichier catalina.properties :

# catalina.properties
datasource.url=jdbc:database://server:1234/schema
datasource.username=dbusername
datasource.password=dbpassword

La substitution des propriétés ne se limite pas au fichier server.xml. Elle s’applique à la majorité des fichiers XML de configuration de Tomcat, notamment :

  • la configuration globale (conf/server.xml, conf/context.xml, conf/web.xml) ;

  • la gestion des utilisateurs (conf/tomcat-users.xml) ;

  • la configuration des applications (fichiers de contexte, web.xml, fragments web).

Par défaut, Tomcat ne remplace les placeholders qu’à partir des propriétés système. Toutefois, à l’image de frameworks comme Spring Boot ou Quarkus, il est possible d’enrichir ce mécanisme grâce aux property sources.

Variables d’environnement

Tomcat peut être configuré pour lire les propriétés à partir des variables d’environnement. Pour cela, il faut déclarer une source de propriétés spécifique avec org.apache.tomcat.util.digester.PROPERTY_SOURCE en propriété système ou dans catalina.properties :

# catalina.properties
org.apache.tomcat.util.digester.PROPERTY_SOURCE=org.apache.tomcat.util.digester.EnvironmentPropertySource

Les variables sont ensuite définies dans l’environnement, par exemple via setenv.sh :

# setenv.sh
DB_URL=jdbc:database://server:1234/schema
DB_USERNAME=dbusername
DB_PASSWORD=dbpassword

Elles peuvent alors être utilisées directement dans les fichiers de configuration :

<Resource name="jdbc/my-global-ds"
          type="javax.sql.DataSource" auth="Container"
          driverClassName="org.database.Driver"
          url="${DB_URL:-jdbc:derby://localhost:1527/sewadb}"
          username="${DB_USERNAME}"
          password="${DB_PASSWORD}" />

Avec Kubernetes

Dans un environnement Kubernetes, Tomcat propose une source de propriétés dédiée permettant d’exploiter les mécanismes de service binding :

# catalina.properties
org.apache.tomcat.util.digester.PROPERTY_SOURCE=org.apache.tomcat.util.digester.ServiceBindingPropertySource

Propriétés système

Le comportement par défaut concernant les propriétés système peut être ajusté. Par exemple, il est possible de désactiver leur remplacement automatique :

# catalina.properties
org.apache.tomcat.util.digester.REPLACE_SYSTEM_PROPERTIES=false

Source de propriétés personnalisée

Tomcat permet également de définir une source de propriétés personnalisée en implémentant l’interface PropertySource.

Exemple d’implémentation :

public class CustomPropertySource implements PropertySource {

  public String getProperty(String key) {
    ...
  }

}

Cette source personnalisée est ensuite déclarée dans org.apache.tomcat.util.digester.PROPERTY_SOURCE.

Cette personnalisation ouvre de nombreuses possibilités :

  • lecture depuis un autre fichier de propriétés ;

  • utilisation de formats alternatifs (XML, YAML, etc.) ;

  • gestion de valeurs chiffrées ;

  • intégration avec un caveau de secrets.

Ce type de mécanisme existe par exemple dans JBoss Web Server, où l’utilisation d’un caveau de secrets est nativement supportée.