1. Introduction
L'objectif du système de déploiement décrit ici est de permettre aux équipes d'exploitation de gérer la tâche de déploiement d'une nouvelle version de JCMS tout en prenant en compte les spécificités de JCMS (stockage des données dans le store, modules, ...)
Ce processus de déploiement peut être utilisé avec toutes les versions de JCMS en cours de maintenance.
Note : Avant l'introduction du processus expliqué dans cette article, le déploiement d'une nouvelle version de JCMS s'effectuait avec le Deploy Manager. Cette application web ne permettait pas d'automatiser le processus de déploiement, ce qui pouvait gêner les équipes d'exploitation. Le Deploy Manager est toujours utilisable avec JCMS en attendant votre transition sur le nouveau système de déploiement présenté ici.
2. Principes
2.1 Organisation de fichiers
Le nouveau système de déploiement repose sur la séparation des données de la partie applicative de JCMS. L'architecture se rapproche ainsi d'un modèle 3-tiers plus habituel pour les équipes d'exploitation. Pour parvenir à cette séparation, les données de JCMS sont externalisées en dehors du répertoire de la webapp au moyen de liens symboliques. Ce choix technique impose 2 contraintes :
- l'utilisation d'un système d'exploitation moderne supportant les liens symboliques (e.g.: Unix/Linux, Windows Server 2008 ou plus récent, ...)
- la configuration du serveur d'application pour lui permettre de suivre les liens symboliques lors de la récupération des fichiers demandés par l'utilisateur
Après cette première mise en place de l'architecture, le processus de mise à jour d'une application est le suivant :
- Les développeurs modifient la webapp (développements, ajout de modules de nouveautés applicatives, migration de version, ...).
- Le mainteneur récupère une version de la webapp et génère un nouveau war complet.
- L'exploitant déploie ce war sur la production en une ligne de commande grâce au script fournit par Jalios (deploy.sh sous Unix ou deploy.ps1 sous Windows)
Le script déploie les modifications applicatives (fichiers statiques, jsp, plugins, classes, librairies, ...) et structurelles (workflows, types). Toutes les données de l'environnement de production sont conservées (upload, archives, store, propriétés, log, monitoring, index lucene, ...).
2.2 Le script de déploiement
Un script de déploiement est fourni pour Unix et pour Windows.
Télécharger les scripts de déploiement (Jalios JCMS Deploy Tools) :
Le script de déploiement requiert un environnement d'exécution spécifique selon la plateforme cible :
- Sur Unix/Linux : Bash
- Sur Windows : PowerShell V2
3. Application du processus
3.1 Mise en place initiale
3.1.1 Externalisation des données de la webapp
L'objectif de cette première étape est de séparer les données gérées par JCMS en les déplaçant en dehors de la webapp.
Cette configuration doit être effectuée une seule fois, au début de la vie du site :
- Déplacez les 3 répertoires suivants hors de la webapp, dans un répertoire dédié au stockage des données.
archives/
upload/
WEB-INF/data/
- Créez des liens symboliques absolus (e.g.:
/opt/jcms/webapp-data/
, pas../foobar/webapp-data
) pour référencer chacun de ces répertoires dans la webapp.- Sous linux :
ln -s /opt/jcms/webapp-data/archives /tomcat/webapp/archives ln -s /opt/jcms/webapp-data/upload /tomcat/webapp/upload ln -s /opt/jcms/webapp-data/WEB-INF/data /tomcat/webapp/WEB-INF/data
- Sous windows (à exécuter dans une commande DOS, en tant qu'administrateur). Important : la webapp et les répertoires cibles des liens symboliques doivent se trouver sur le même volume Windows.
mklink /D "C:\webapp\archives" "c:\webapp-data\archives" mklink /D "C:\webapp\upload" "c:\webapp-data\upload" mklink /D "C:\webapp\WEB-INF\data" "c:\webapp-data\WEB-INF\data"
- Sous linux :
Ces contraintes sont vérifiées par le script de déploiement (qui n'effectuera aucune modification si elles ne sont pas respectées).
3.1.2 Configuration des serveurs d'applications
Selon le serveur d'application, il est peut-être nécessaire d'indiquer que les liens symboliques doivent être suivis. Sans cela la récupération des fichiers du répertoire upload ou archives pourrait provoquer une erreur HTTP 404.
Tomcat :
Sur environnement Linux uniquement, il est nécessaire de configurer l'attribut allowLinking
de la webapp.
Important : Pour garantir la sécurité de l’application, ne positionnez en aucun cas cet attribut dans un environnement Windows.
Cette option se configure soit dans le fichier conf/server.xml
, soit dans le contexte par défaut (conf/context.xml
) soit dans un fichier de contexte dédié à la webapp. L'attribut doit être positionné sur la balise Context
pour Tomcat 7.x et sur la balise fille Resources
pour Tomcat 8.x :
<!-- Tomcat 7: -->
<Context allowLinking="true" />
<!-- Tomcat 8: -->
<Context>
<Resources allowLinking="true" />
</Context>
IBM WebSphere :
- Ouvrez la console d’administration de WebSphere
- Allez dans Application Servers > server 1 > Web container > Custom properties
- Ajouter la propriété com.ibm.ws.webcontainer.TolerateSymbolicLinks avec la valeur true
Oracle WebLogic :
Aucune configuration n'est nécessaire. Les liens symboliques sont nativement suivis par WebLogic.
Glassfish Server :
- Ouvrez la console d’administration de GlassFish
- Allez dans Configuration > Virtual Servers > Server
- Ajoutez la propriété additionnelle allowLinking à true
3.2 Préparation du war de déploiement
Une fois les développements terminés, préparez le nouveau war en suivant les indications ci-dessous :
- Récupérez une copie complète de la production.
- Celle-ci doit impérativement contenir les modules.
- La présence des répertoires
upload
,archives
,log
ou autre données n'a aucune importance pour le déploiement ultérieur, récupérez les si vous en avez besoin pour vos développements.
- Effectuez et validez vos développements ...
- Dernière étape : packagez la nouvelle version de la webapp dans un war en respectant les contraintes suivantes :
- La présence de tous les modules est impérative.
- La présence du fichier
store.xml
n'est nécessaire que si des modifications doivent être réincorporées en production - Il est inutile de mettre les répertoires
upload
etarchives
dans ce nouveau war car ils seront ignorés, et cela alourdirait le war pour rien. - Il est inutile de mettre les répertoires ou fichiers suivants (cependant les laisser dans le war n'a aucune incidence sur le déploiement) :
- Base derby (
WEB-INF/data/derby
) - Index lucene (
WEB-INF/data/lucene
) - Statistiques, logs, monitoring, backup, ... (
WEB-INF/data/stats/
,WEB-INF/data/logs/
,WEB-INF/data/jsynclog/
,WEB-INF/data/backups/
,WEB-INF/data/monitoring.xml
)
- Base derby (
3.3 Déploiement du war sur le serveur
Déploiement simple :
Ce type de déploiement conviendra dans 80% des cas
- Déposez le fichier war à déployer sur le serveur
- Arrêtez le serveur J2EE
- Lancez le script de déploiement
- Unix :
./deploy.sh nouveau.war répertoire-webapp/
- Windows :
&"C:\jalios-deploy\deploy.ps1" c:\nouveau.war c:\tomcat\webapps\jcmswebapp
- Unix :
- Redémarrez le serveur J2EE
Déploiement avancé :
- Gestion des données du store :
- Utilisez l'option
-s "merge"
pour fusionner le store de la production et le store du war (une sauvegarde est effectuée avant modification). En cas de conflit(s) détecté(s), le déploiement est interrompu et un retour arrière est effectué pour rétablir la webapp dans son état initial. - Utilisez l'option
-s "overwrite"
pour remplacer le store de la production par le store du war (une sauvegarde est effectuée avant modification)
- Utilisez l'option
- Répertoire de stockage des sauvegardes
- L'option
-b
(-BackupDirectory
sur Windows) permet de spécifier un répertoire pour le stockage des sauvegardes. A la fin du processus de déploiement, la webapp originale est normalement sauvegardée dans le même répertoire dans lequel elle se trouvait, simplement suffixée avec la date de déploiement. Pour éviter que cette sauvegarde interfère avec le fonctionnement du serveur J2EE (par exemple avec Tomcat en mode déploiement automatique dans le répertoire webapp), il est possible de spécifier un autre répertoire dans lequel la webapp original sera déplacée, grâce à cette option-b
.
- L'option
- Test
- L'option -
d
(-DryRun
sur Windows) permet de faire un test de déploiement. Dans ce mode, aucune modification n'est effectuée, seuls les prérequis sont vérifiés et les opérations qui auraient été effectuées sont indiquées.
- L'option -
- Mode verbeux
- L'option
-v
(-Verbose
sur Windows) permet d'obtenir des logs détaillés sur l'exécution du scriptdeploy.sh
(utile pour le support, pour débugger ou pour comprendre le fonctionnement du script)
- L'option
Note : les noms courts des paramètres sont le plus possible identiques entre le script Unix et le script Windows (pour plus de détails, consultez l'usage de chacun des scripts en l'exécutant sans aucun paramètre).
4. Description avancée du script
4.1 Gestion d'erreur et sauvegarde
- rollback : en cas d'échec du déploiement (disque plein, échec de la fusion du store, autre erreur) un rollback est effectué et la webapp revient à son état initial.
- sauvegarde : si le
store.xml
est fusionné ou remplacé, la version existante est sauvegardée - structure : les
types
etworkflows
de la production sont sauvegardés avant d'être remplacés par ceux du war
4.2 Récupération des données du war
- upload : Le répertoire
upload
n'est pas récupéré du war. Il ne peut pas y avoir de nouveau document ajouté via ce mécanisme de déploiement. - propriétés : Le répertoire
WEB-INF/data
n'est par récupéré du nouveau war (sauf store.xml, types et workflow). Les fichiers propriétés qui serait modifiés dans le war (custom.prop
,webapp.prop
) ne sont donc pas déployés. Le script de déploiement peut être modifié ou complété avec un autre script pour répondre à un besoin différent.
4.3 Différences entre la version Windows et la version Unix du script
La version Windows du script de déploiement ne propose pour l'instant pas toutes les fonctionnalités de la version Unix :
- la version Windows n'empêche pas le déploiement d'un war contenant moins de modules que la webapp cible
- la version Windows n'enregistre pas la liste des différences de déploiement dans le fichier WEB-INF/data/logs/deploy.log (diff des fichiers et répertoires des 2 webapps avant/après)
- la version Windows n'effectue pas de rollback si le script est interrompu manuellement (eg : ctrl-c) lors de son exécution
- la version Windows requiert des modules PowerShell annexes fournis avec le script (pour dezipper et pour la gestion des liens symboliques)
De plus la version Windows impose des contraintes supplémentaires :
- Le war à déployer, le répertoire de la webapp, les répertoires cibles des liens symboliques et le répertoire temporaire doivent se trouver sur le même volume Windows (cf sections 3.1.1 et 5.3)
5. FAQ : Questions/Réponses
5.1 Message d'erreur "l’exécution de scripts est désactivée" sur Windows
Problème :
Lors de l'exécution du script, vous obtenez le message d'erreur suivant :
Impossible de charger le fichier C:\jalios-deploy\deploy.ps1, car l’exécution de scripts est désactivée sur ce système. Pour plus d’informations, consultez « get-help about_signing ».
Solution :
Il existe 4 stratégies d'exécution de PowerShell sous Windows, la stratégie par défaut ne permettant notamment pas l'exécution des scripts locaux non signés :
- Restricted : Stratégie par défaut, Les scripts ne sont pas autorisés
- AllSigned : Les scripts peuvent être exécutés mais seulement s’ils sont signés
- RemoteSigned : Les scripts exécutés localement peuvent être exécutés sans être signés, les scripts téléchargés à partir d’internet doivent être signés
- Unrestricted : Tous les scripts signés ou non peuvent être exécutés
Ouvrez l’interpréteur PowerShell et entrez la commande suivante afin de changer de mode, pour autoriser l’exécution de script locaux :
PS C:\> Set-ExecutionPolicy RemoteSigned
Vous pouvez vérifier que le changement a bien été effectué en tapant la commande suivante :
PS C:\> Get-ExecutionPolicy
RemoteSigned
Ouvrez ensuite les propriétés du fichier deploys.ps1
et dans l'onglet général, cliquez sur le bouton Débloquez afin de certifier la provenance du fichier et de rendre son exécution locale possible.
5.2 Message d'erreur "Could not extract Web Archive" sur Windows
Problème :
Lors de l'exécution du script, vous obtenez le message d'erreur suivant :
Unzip-War : Could not extract Web Archive : Le chemin d'accès spécifié, le nom de fichier ou les deux sont trop longs.
Le nom de fichier qualifié complet doit comprendre moins de 260 caractères et le nom du répertoire moins de 248 caractères.
Solution :
Passez à Unix, vous aurez moins de soucis, et au passage vous pourrez abandonner IE 6, bonne nouvelle non !?
Plus sérieusement : redéfinissez la variable TEMP de votre environnement Windows (dans la console d'exécution PowerShell) afin que le répertoire temporaire utilisé soit situé dans un chemin le plus court possible.
Set-Item -path env:temp -value "C:\temp"
5.3 Message d'erreur "Move-Item : Le chemin d'accès source et celui de destination doivent avoir des racines identiques." sur Windows
Problème :
Lors de l'exécution du script, vous obtenez le message d'erreur suivant :
Move-Item : Le chemin d'accès source et celui de destination doivent avoir des racines identiques. Le déplacement n'est
pas possible entre ces volumes
Solution :
Passez à Unix (ah... mince, on l'avait déjà dit pourtant...:)
Ou sinon : assurez-vous que le war à déployer, le répertoire de la webapp, les répertoires cibles des liens symboliques, et le répertoire temporaire sont sur le même volume (eg : pas C:\webapp et D:\webapp.war mais C:\webapp et C:\webapp.war).
Vous pouvez forcer le répertoire temporaire avec la commande suivante :
Set-Item -path env:temp -value "C:\temp"
5.4 Comment consulter l'historique des déploiements passés (log)
Vous pouvez consulter l'historique des déploiements qui ont été effectués sur votre applicatif en consultant le fichier WEB-INF/data/logs/deploy.log
.
Voici un exemple de commande Unix permettant de visualiser les précédents succès de déploiement (le résultat de la commande a été légèrement ré-écrit par souci de lisibilité) :
$ grep "Done deploying" WEB-INF/data/logs/deploy.log 28 jan 18:46:09 2011 - Done deploying war '[...]/tmp/jn-7.0.0-1055.war'. 13 avr 09:46:53 2011 - Done deploying war '[...]/tmp/jn-7.0.1-1298.war'. 14 avr 17:14:36 2011 - Done deploying war '[...]/tmp/jn-7.0.1-1311.war'. 3 oct 11:12:31 2011 - Done deploying war '[...]/tmp/jn-7.0.2-1614.war'. 7 oct 11:33:15 2011 - Done deploying war '[...]/tmp/jn-7.0.2-1630.war'. 27 déc 10:15:46 2011 - Done deploying war '[...]/tmp/jn-7.0.3-1800.zip'.
5.5 Comment gérer le déploiement du fichier web.xml
Le fichier WEB-INF/web.xml
est un composant applicatif capital de la webapp, il fait parti intégrante de l'application JCMS et à ce titre nous considérons que c'est la version de la nouvelle webapp qui doit être déployé.
En effet, ce fichier décrit par exemple les servlet filter et les mappings lié à la sécurité et à l'authentification native JCMS, ainsi qu'au téléchargement ou à d'autres fonctionnalité coeur du produit.
En spécifique il peut y être rajouter des pages d'erreurs, des durée de session différentes, des configurations spécifiques de SSO, etc,
Mais dans tous les cas ce fichier fait parti de la webapp et on ne peut pas réutiliser celui de la production sans crainte d'omettre des informations importante lié à l'applicatif JCMS.
C'est pour cela que le fichier de la nouvelle webapp doit toujours être privilégié et que nous recommandons la génération d'un war avec le bon fichier web.xml
.
Cependant, si pour une raison X ou Y vous souhaitez utiliser le fichier web.xml
de la production, cela peut se faire en spécifique de façon trivial via une sauvagarde prealable à l'utilisation du script de déploiement puis via écrasement après son invocation. Faites ce choix avec prudence et en connaissance de cause.