Faire un don

Comment créer sa WebApp ?

Pour cela, nous allons partir d’un cas concret : le moteur de blog DotClear
http://dotclear.org/

Il faut compter environ 2H la première fois qu’on prépare une WebApp, mais une fois qu’on l’a fait une fois, 20 à 30mn suffisent.

Je vous conseille (voir je vous impose !) la lecture de la FAQ avant de poursuivre, car les informations sur les fichiers de configurations qui y sont données ne seront pas répètées ici !

Préparation

Comme en cuisine, il nous faut quelques ingrédients.

Et les WebApps, c’est comme les yaourts : on peut tres bien se baser sur un yaourt déjà fait pour aider à la fermentation des autres, plutôt que d’acheter la levure ou les ferments ailleurs.

Donc, on va commencer par partir de WordPress portable (le fait que Dotclear et WordPress soient tous deux des blogs n’a strictement aucune incidence, ça n’est qu’une coïncidence).
Fermez d’abord toutes les WebApss qui pourraient être lancées.

Téléchargeons WordPress Portable : http://files.framakey.org/webapps/WordPressPortable.zip
Téléchargeons aussi la dernière version .zip de Dotclear : http://download.dotclear.net/latest-2.0.zip

Dézippons ces deux fichiers dans 2 dossiers différents.

C’est parti !

Renommez le dossier WordPressPortable en DotclearPortable.
Dans ce dossier, renommez WordPressPortable.exe en DotclearPortable.exe (oui, l’icône reste la même, on s’en occupera à la fin).

Bien, normalement, si vous double-cliquez sur DotclearPortable.exe, que se passe-t-il ?

Je résume à gros traits avant de rentrer dans les détails.

1. DotclearPortable.exe va lancer /Others/Framakey-WebAppManager/Framakey-WebAppManager.exe (que je vais appeller “WAM” ou “le Manager” dans le reste de ce tutoriel).
2. WAM va charger son fichier de configuration situé dans /Others/Framakey-WebAppManager/Framakey-WebAppManager.ini
3. WAM va charger le fichier de configuration de la WebApp situé dans /App/AppInfo/appinfo.ini
4. WAM va charger et générer les menus des scripts génériques /Others/Framakey-WebAppManager/scripts.generic.ini et des scripts spécifiques /App/AppInfo/scripts.ini
5. WAM va lancer le serveur Web (ZMWS) et le gestionnaire de base de données (MySQL)
6. WAM va executer le script de démarrage, situé dans /App/AppInfo/startup.ini, qui va notamment servir à indiquer à l’application quel sont les ports utilisés.

Voilà dans les grandes lignes. Pour ceux qui n’auraient pas suivis, on a donc 2 dossiers clés :

  • /Others/Framakey-WebAppManager/ dans lequel se trouve des informations valables pour toutes les WebApps, ou propre à WAM.
  • /App/AppInfo/ dans lequel on retrouve les informations spécifiques à la WebApp.

Commençons donc par ce dernier dossier.

Un peu de ménage

Commençons par bouter WordPress hors de la WebApp.
Cela se fait très simplement :

  1. supprimez le dossier /App/wordpress/ qui contient l’application WordPress.
  2. supprimez le dossier /App/data/wordpress/ qui correspond à la base MySQL
  3. supprimez le fichier /App/Appinfo/scripts.ini qui correspond aux scripts spécifiques wordpress

Bye bye WordPress !

Maintenant, ouvrons /App/AppInfo/appinfo.ini
Ce fichier est en effet le plus important. C’est lui qui décrit notre WebApp.

[Format]
Type=Framakey.orgFormat
Version=0.9.8

[Details]
Name=Framakey WordPress Portable
Publisher=WordPress, Framakey
Homepage=Framakey.org/WordPressPortable
Category=Blog
Description=WordPress Portable.

[License]
Shareable=true
OpenSource=true
Freeware=true
CommercialUse=true

[Version]
PackageVersion=2.7.0.0
DisplayVersion=2.7

[Control]
Icons=1
Start=WordPressPortable.exe

[WebAppSpecific]
ShortName=WordPress
ApplicationPath=wordpress
DatabaseName=wordpress
Website=http://www.wordpress.org
Support=http://wordpress.org/support/
Framasoft=http://www.framasoft.net/
FramasoftSupport=http://forum.framasoft.org/
Logo=logo.gif

Modifions le en :

[Format]
Type=Framakey.orgFormat
Version=0.9.8

[Details]
Name=Framakey Dotclear Portable
Publisher=WordPress, Framakey
Homepage=Framakey.org/WebApp
Category=Blog
Description=Dotclear Portable.

[License]
Shareable=true
OpenSource=true
Freeware=true
CommercialUse=true

[Version]
; version du package WebApp
PackageVersion=2.1.5
; Version affichée à l'écran
DisplayVersion=2.1.5

[Control]
; non utilisé
Icons=1
; non utilisé
Start=DotclearPortable.exe

[WebAppSpecific]
; Important : il s'agit de l'indentifiant de l'application. Les espaces sont autorisés, mais à vos risques et périls :P
ShortName=Dotclear
; nom du dossier de la WebApp dans le dossier /App/
ApplicationPath=dotclear
; nom de la base de données
DatabaseName=dotclear
; les champs suivants parlent d'eux mêmes
Website=http://www.dotclear.org
Support=http://forum.dotclear.net/
Framasoft=http://www.framasoft.net/article1955.html
FramasoftSupport=http://forum.framasoft.org/
; chemin relatif du logo qui sera affiché dans le splashcreen
Logo=logo.gif

Les lignes commençant par “;” sont des commentaires, vous pouvez les conserver ou pas.
En réalité, seul les entrées [Version] et [WebAppSpecific] seront utilisées.

Nous avons changé le plus important, à savoir les valeurs ShortName, ApplicationPath et DatabaseName.

Dernière étape, copions le dossier “dotclear” précédemment téléchargé et dézippé dans le dossier /App (de façon à obtenir /App/dotclear/index.php)

Après le ménage, l’habillage.

Récupérez un logo de Dotclear (les logos sont souvent proposés sur les sites officiels, sinon Google Images peut donner des résultats intéressants.

Redimensionnez cette image avec Gimp (ou autre), mettez une largeur ou hauteur maximum de 128 pixels (l’image n’a pas forcément à être carrée), de préférence avec un fond blanc. Enregistrez-là en écrasant /App/AppInfo/logo.gif (vous pouvez evidemment mettre un autre nom, ou un format JPG ou PNG, mais pensez à adapter l’enrée “Logo=logo.gif” du fichier /App/AppInfo/appinfo.ini vu précédemment.

Tant que vous y êtes (dans Gimp), redimensionnez-là en 16×16 pour en faire une icone nommée /App/AppInfo/appicon.ico. Gimp sait parfaitement gérer ce genre de fichier.

Vous y êtes ? Félicitations, la moitié du chemin est faite !

Beta testons tous en choeur

Lancez DotClearPortable.exe.
Vous noterez que dans le splashscreen c’est “Dotclear” ainsi que son logo qui s’affichent, car c’est la variable “ShortName” qui est utilisée.

Si vous avez des erreurs au démarrage, c’est normal ! Pas d’inquiétude.

Si vous cliquez sur l’icone près de l’horloge (qui devrait maintenant avoir l’icone de dotclear) et cliquez sur “Ouvrir Dotclear”, vous devriez tomber sur la page d’installation qui ressemble à ça :

C’est bien ça ? Parfait.

Dans le Manager, cliquez donc sur “MySQL > Eskuel”. Un autre fenêtre s’ouvre.

  • Cliquez sur “Create database” à droite (les anglophobes peuvent changer la langue s’ils le souhaitent).
  • Saisissez “dotclear” (tout en minuscules, et sans les guillemets !)
  • validez. Bravo ! Votre base est créée
  • retournez dans dotclear, et suivez la procédure d’installation en cliquant sur “You can create a config.php file through a web interface” puis “wizard”
  • remplissez les champs : “Database Host Name = localhost”, “Database Name = dotclear” (en minuscules, on vous a dit) et “Database User Name = root”. Il n’y a pas de mot de passe (il ne va y avoir que la base “dotclear” dans votre WebApp).
  • Validez et…

Paf, une erreur “Mysql Innodb engine not available” (ha ben oui, je portabilise en même temps que je fait le tuto, moi ! :P )

Pourquoi cette erreur ?
Parce que Dotclear a besoin d’une option MySQL (le moteur InnoDB) qui est désactivé par défaut dans les WebApps. Mais qu’à cela ne tienne, c’est simple à corriger winking smiley

  • Quittez votre WebApp
  • Rendez vous dans /Others/Framakey-WebAppManager/Framakey-WebAppManager.ini
  • ajoutez skip-innodb=False sous l’entrée [MySQL] de façon à obtenir
[MYSQL]
port=Auto
skip-innodb=False
  • Redémarrez votre WebApp et reprenez la procédure, tout devrait mieux se passer winking smiley
  • finissez l’installation (ici j’ai mis “admin” et “framasoft” comme login/password)

Dotclear va maintenant créer la base et finir l’installation.

Victoire .

?!

Bon, nous avons maintenant un dotclear fonctionnel. Et ça c’est une bonne nouvelle.

Maintenant, ce n’est pas encore une WebApp. Par exemple, si je lance Drupal portable puis Dotclear Portable, Dotclear va toujours croire qu’il doit se lancer à l’adresse 127.0.0.1, port web 80, et port mysql 3306. Or Drupal Portable “squatte” déjà ces deux emplacements.

Il va donc falloir peaufiner notre application pour qu’au démarrage, elle sache se mettre à jour toute seule comme une grande.

Une femme dans chaque port, et un port pour chaque WebApp

Sous ce titre ridicule se cache la partie un peu “tricky” (non, pas l’ancien de Massive Attack !) de la portabilisation. Prenez une inspiration ou deux, concentrez vous (Tricky, l’artiste cette fois, est pas mal pour ça), et lançons nous.

Il va falloir demander à WAM d’executer à chaque lancement de Dotclear portable une succesion d’instructions de mise à jour.

Il faudra systématiquement adapter :
- le port MySQL (pour dotclear et eskuel). Par défaut, c’est 3306.
- le port web (pour que ZMWS “trouve” dotclear). Par défaut, c’est le port 80.
Là, il faut connaitre un peu l’application en question, mais n’importe quel développeur connaissant Dotclear saura vous aiguiller.
Notez que la procédure revient en fait quasi systématiquement :
1. à modifier un fichier de configuration (pour le port MySQL)
2. à adapter une ou deux entrées la base de données pour le port web.

Rassurez-vous, c’est plus simple à faire qu’à expliquer winking smiley

Commençons par le plus simple, le port de Eskuel (l’application qui vous permettra d’acceder à la base de données).

  • Arrêtez Dotclear Portable
  • ouvrez /App/AppInfo/startup.ini
  • Videz son contenu et insérez
[UpdateEskuelPort]
Name=Syncronize Eskuel Port
Description=Update Eskuel config with the Open MySQL Port
Type=REPLACE
File={$root_path_absolute}\ZMWS\_web.zmwsc\_vhosts.zmwsc\127.0.0.2\eskuel\config.inc.php
SearchPattern=127.0.0.1(:\d*)?
ReplaceValue=127.0.0.1:{$mysql_port}

Que dit ce morceau de script ?
“Je crée un nouveau script ‘UpdateEskuelPort’ avec un nom et une description. Ce script est de type ‘REPLACE’, c’est donc un rechercher-remplacer. Il va ouvrir le fichier config.inc.php de Eskuel, chercher la chaine ‘127.0.0.1′ (suivi ou non du signe ‘deux points’ et d’un ou plusieurs chiffres). C’est ce qu’on appelle une expression régulière, et Wikipédia vous renseignera mieux que moi. Ensuite on remplace ce qu’on a trouvé par ‘127.0.0.1:’ suivi du premier port mysql libre qu’on aura trouvé (3306, 3307, 3308, etc).”

Ainsi, à chaque démarrage de Dotclear Portable, le port de l’application Eskuel sera mis à jour.

Si vous voulez savoir à quoi correspondent , et compagnie, lisez la FAQ

Et pour notre Dotclear ?

D’abord, il faut repérer le fichier MySQL ou se fait la connexion à la base de données.
C’est le plus souvent le fichier de configuration principal.
Pour Dotclear, c’est donc : \App\dotclear\inc\config.php
Ensuite, on cherche la ligne qui indique l’hôte MySQL.
Pour nous, il s’agit de :

define(‘DC_DBHOST’,’localhost’);

Il faudra donc la remplacer à chaque démarrage par

define(‘DC_DBHOST’,’localhost:XXXX’);

où XXXX sera le numéro de port MySQL.

On va donc ajouter à startup.ini une nouvelle entrée :

[UpdateMySQLPort]
Name=Update Eskuel Port
Description=Update Eskuel config with the Open MySQL Port
Type=REPLACE
File={$root_path_absolute}\App\{$ApplicationPath}\inc\config.php
SearchPattern=define\('DC_DBHOST','localhost(:\d*)?'\);
ReplaceValue=define('DC_DBHOST','localhost:{$mysql_port}');

(notez que dans le motif de recherche on a echappé les caractères spéciaux)

Relancons DotClear portable, puis ouvrons config.php. On trouve maintenant la ligne

define(‘DC_DBHOST’,’localhost:3306′);

Magnifique, ça a marché winking smiley

Maintenant, il faut faire la même chose pour le port web.
Pour l’instant, on sait que l’adresse est http://127.0.0.1/dotclear (ce qui correspond en fait à http://127.0.0.1:80/dotclear (80 étant le port web par défaut).
Cependant, si d’autres WebApps sont lancés, on y accèdera peut être par http://127.0.0.1:8080/dotclear ou http://127.0.0.1:8081/dotclear
Il faut donc là aussi indiquer à WAM de mettre à jour le port.

Souvent, cette information se trouve dans la base de données. Pour Dotclear, l’info se trouve en partie dans le même fichier config.php que tout à l’heure. On trouve :

define(‘DC_ADMIN_URL’,’http://127.0.0.1/dotclear/admin/’);

On va donc encore ajouter un script à notre startup.ini

[UpdateWebPort]
Name=Update web Port
Description=Update dotclear config with the open web Port
Type=REPLACE
File={$root_path_absolute}\App\{$ApplicationPath}\inc\config.php
SearchPattern=define\('DC_ADMIN_URL','http://127.0.0.1(:\d*)?/dotclear/admin/'\);
ReplaceValue=define('DC_ADMIN_URL','http://127.0.0.1:{$zmws_port}/dotclear/admin/');

Voilà pour l’admin.

Oui, mais pour les billets ?

L’info se trouve dans la table “dc_blog”. C’est là qu’est indiquée en dur, l’URL du blog.

On va donc vouloir executer la requête suivante à chaque démarrage de DotclearPortable :

[UpdateBlogUrlValues]
Name=Update Options table
Description=Update dotclear "blog" table with some real config values
Type=SQL
Query=UPDATE `dc_blog` SET `blog_url`='http://127.0.0.1:{$zmws_port}/dotclear/index.php?' WHERE `blog_status`='1';

Cette dernière entrée dans le fichier startup.ini va donc correspondre à une requête SQL mettant à jour le port Web dans la base de données.
(là, je l’ai jouée un peu bourrin, on aurait pu faire une requête plus propre avec un remplacement de partie de chaine, envisageant le cas où l’on aurait du multiblog. Mais bon, c’est pour la démonstration).

Maintenant, testons tout cela :

  • Quittons DotclearPortable
  • Lançons WordPressPortable (ou une autre WebApp)
  • Puis lançons DotclearPortable

Ca marche !

Ha oui, mais non !
Ca va marcher la première fois, mais Dotclear utilisant un (performant) système de cache, ce dernier pourrait nous mettre dans la mouise si le port venait à changer une prochaine fois.

Donc, on va se logguer en administrateur dans dotclear ( http://127.0.0.1:8080/dotclear/admin/ ), et dans le menu de gauche “about:config” passer la valeur “tpl_use_cache” à “no” (à faire dans l’onglet “blog settings” et dans l’onglet “global settings”).

Evidemment, on perdra en performance, mais les WebApps ne sont pas destinées à être utilisée en production avec des milliers de visiteurs par jour. Donc s’il s’agit d’un blog en construction, désactiver le cache sera pluôt un avantage.

Voilà !

La fin était un peu perilleuse, j’en conviens.
Mais l’avantage, c’est qu’il est possible de partager publiquement les contenus des fichiers startup.ini, et donc de les affiner collectivement.

Dans un prochain tuto, je reviendrais sur les scripts personnalisés…