Development

Documentation/fr_FR/askeet/trunk/D22

You must first sign up to be able to contribute.

Version 14 (modified by karen, 10 years ago)
--

Cette partie de la documentation est en cours de traduction. Cela signifie qu'elle est traduite de manière soit incomplète, soit inexacte. En attendant que cette traduction soit terminée, vous pouvez consulter la version en anglais pour des informations plus fiables.

Calendrier de l'avent vingt-deuxième jour : vers la production

Précédemment dans Symfony

Hier nous avons ajouté un back-office à askeet. L'application est donc prête à tourner et peut être publiée sur Internet (d'ailleurs, elle y est déjà et si vous l'avez pas encore fait, vous pouvez la consulter en ligne sur www.askeet.com). Le moment est donc venu d'entrer dans les détails techniques liés à la synchronisation de deux serveurs, puisque vous avez développé askeet sur votre ordinateur et allez probablement l'héberger sur une autre machine, un serveur connecté à Internet.

Synchronisation

Bonnes pratiques

Il existe de nombreuses manières de synchroniser deux environnements pour gérer un site Web. On peut par exemple utiliser un simple tranfert de fichier par FTP, mais cette solution présente deux défauts majeurs. D'abord, elle n'est pas sûre, car le flux de données transite en clair sur Internet et peut être intercepté. Ensuite, si envoyer tout le répertoire racine du projet par FTP peut se justifier lors d'un premier transfert, ce n'est pas la manière la plus rapide et la plus efficace de procéder lors de la mise à jour de votre application, quand seuls quelques fichiers auront été modifiés. Dans ce cas, soit vous mettez à jour tout le projet, ce qui peut prendre du temps, soit vous naviguez dans les répertoires dans lesquels vous savez que certains fichiers ont été modifiés et ne transférez que ceux ayant une date de modification plus récente. C'est un travail long, générateur d'erreurs. En outre, votre site Web peut se trouver indisponible ou instable pendant le transfert.

La solution adoptée par symfony est d'utiliser une synchronisation par rsync, à travers une couche SSH.

Rsync est un utilitaire en ligne de commande qui fournit un transfert de fichier rapide et incrémental, et open source. Incrémental car seules les données modifiées seront transférées. Si un fichier n'a pas changé, il ne sera pas envoyé au serveur. Si un fichier n'a été que partiellement modifié, seules les différences seront envoyées. Les synchronisation rsync ont donc pour principal avantage de ne transférer que le minimum de données, très rapidement.

Symfony ajoute une couche SSH à rsync afin d'assurer la sécurité du transfert de données. De plus en plus d'hébergeurs commerciaux proposent un tunnel SSH pour sécuriser le transfert de fichiers sur leurs serveurs, ce qui est une bonne pratique, encouragée par symfony.

Pour plus de détails sur l'installation de rsync et SSH sur Linux, lisez les instructions données sur les sites correspondants. Pour Windows, une version spécifique de rsync existe, cwRsync, vous pouvez également essayer d'installer les binaires à la main (vous trouverez les instructions ici). Bien entendu, pour créer un tunnel entre un serveur d'intégration et un hébergeur, le service SSH doit être installé et lancé sur les deux machines.

La commande sync de symfony

Lancer un rsync avec SSH nécessite plusieurs commandes et on peut être amené à faire de nombreuses synchronisations pour une application. Heureusement, symfony automatise ce processus en une seule commande :

 $ symfony sync production

Cette commande, lancée depuis le répertoire racine d'un projet symfony, lance la synchronisation du code du projet avec le serveur de production. Les détails de connexion à ce serveur doivent être spécifiés dans le fichier properties.ini du projet, sous askeet/config/ :

name=askeet

    [production]
       host=myaskeetprodserver.com
       port=22
       user=myuser
       dir=/home/myaccount/askeet/

Ces propriétés de connexion seront utilisées par l'appel client SHH sous-jacent à la ligne de commande sync de symfony.

Si vous lancez juste la commande sync ci-dessus, l'utilitaire rsync se lancera par défaut en mode blanc (--dry-run) : il vous montrera quels fichiers doivent être synchronisés sans pour autant les synchroniser. Si vous voulez que la synchronisation ait effectivement lieu, vous devez le demander explicitement :

 $ symfony sync production go

Ignorer certains fichiers

Lors de la synchronisation de votre projet symfony avec le serveur de production, un certain nombre de fichiers et de répertoires ne doivent pas être transferrés :

* Tous les répertoires .svn et leur contenu : ils contiennent les informations relatives au contrôle de version, utiles uniquement au développement et à l'intégration 
* askeet/web/frontend_dev.php : le frontend de développement ne doit pas être accessible à l'utilisateur final. Les outils de débuggage et de journalisation disponibles à travers ce contrôleur ralentissent l'application et fournissent des informations sur les variables de vos actions. Ceci ne doit pas apparaître sur le serveur hôte.
* Les répertoires cache/ et log/ du projet ne doivent pas être supprimés sur le serveur hôte à chaque synchronisation. Ces répertoires doivent aussi être ignorés. Si votre projet contient un répertoire stats/, il doit probablement être traité de la même manière.
* Les fichiers chargés par les utilisateurs : une des bonnes pratiques encouragée par symfony consiste à stocker les fichiers chargés par les utilisateurs dans le répertoire web/uploads/. Cela permet d'exclure tous ces fichiers en sélectionnant un seul répertoire.

Pour exclure des fichiers des synchronisations, ouvrez le fichier rsync_exclude.txt sous askeet/config/ et ajoutez-y les fichiers/répertoires à ignorer. Chaque ligne peut contenir un fichier, un répertoire ou une expression régulière.

.svn
web/frontend_dev.php
cache
log
stats
web/uploads

Grâce à la structure de fichiers de symfony, vous n'avez pas à exclure manuellement de la synchronisation trop de fichiers ou de répertoires. Si vous voulez en savoir plus sur l'organisation des fichiers d'un projet symfony, référez-vous au chapître traitant de la structure de fichiers de la documentation de symfony.

NOTE : les répertoires cache/ et log/ ne doivent pas être synchronisés avec le serveur de développement, mais doivent exister sur le serveur de production. Il faut les créer à la main si la structure arborescente du projet askeet ne les contient pas.

Configuration du serveur de production

Pour que votre projet tourne sur le serveur de production, le framework symfony doit être installé sur l'hôte.

Installer symfony sur un serveur de production

Il existe plusieurs manières d'installer symfony sur un serveur, mais elles ne sont pas toutes adaptées à un environnement de production. Ainsi, une installation PEAR nécessite des droits administrateur sur des répertoires qui pourraient ne pas vous être accessibles si vous partagez un serveur Web.

Si on part du principe que vous hébergerez probablement plusieurs projets symfony sur le serveur Web de production, l'installation recommandée consiste à décompresser l'archive du framework dans un répertoire donné. Seuls les répertoires lib/ et data/ sont nécessaires sur le serveur de production, vous pouvez donc vous débarrasser des autres fichiers et répertoires (bin/, doc/, test/ et les fichiers du répertoire racine).

Vous devriez obtenir une structure de fichiers proche de la suivante :

/home/myaccount/    
  symfony/
    lib/
    data/
  askeet/
    apps/
      frontend/
    batch/
    cache/
    config/
    data/
    doc/
    lib/
    log/
    test/
    web/

Pour que le projet askeet puisse utiliser les classes symfony, vous devez créer deux liens symboliques entre les répertoires lib/symfony et data/symfony de l'application et les répertoires correspondants dans l'installation symfony :

$ cd /home/myaccount/askeet
$ ln -sf /home/myaccount/symfony/lib lib/symfony
$ ln -sf /home/myaccount/symfony/data data/symfony

Une autre solution, si vous n'avez pas accès à la ligne de commande, consiste à copier directement les fichiers du framework sous les répertoires lib/ et data/ du projet :

copy /home/myaccount/symfony/lib/*   into /home/myaccount/askeet/lib/symfony
copy /home/myaccount/symfony/data/*  into /home/myaccount/askeet/data/symfony

Notez que dans ce cas, vous devrez le faire pour tous vos projets à chaque mise à jour du framework.

Pour plus d'informations, toutes les manières d'installer symfony sont décrites dans le chapître d'installation de la documentation de symfony.

Accéder aux commandes symfony sur le serveur de production

Lors du développement de votre application, vous avez pris la bonne habitude d'utiliser :

$ symfony clear-cache

... à chaque modification de la configuration ou du modèle objet du projet. Lorsque vous transférez une nouvelle version de votre projet sur le serveur de production, vous devez aussi nettoyer le cache si vous voulez que votre application fonctionne correctement. Vous pouvez facilement le faire en supprimant tout le contenu du répertoire askeet/cache/ (par ftp ou via une console ssh). Vous pouvez également profiter de la puissance de la ligne de commande symfony, moyennant une installation un peu plus longue.

Pour utiliser la ligne de commande symfony, vous devez installer l'utilitaire Pake. Pake est un outil PHP équivalent à make. Il automatise certaines tâches d'administration selon un fichier de configuration spécifique, pakefile.php. La ligne de commande symfony utilise elle-même l'utilitaire Pake, et chaque fois que vous appelez symfony, vous lancez en fait Pake avec un fichier pakefile.php spécial, situé dans le répertoire symfony/bin/ (pour plus de détails sur Pake dans symfony, référez-vous au chapître de création de projet du book). Si vous avez installé symfony via PEAR, Pake est installé par défaut, même si vous ne le voyez pas, et vous n'avez donc pas à vous soucier de ce qui suit. Mais si vous avez fait une installation manuelle, vous devez décompresser le répertoire Pake (dans votre installation pear de symfony) dans le répertoire de votre projet sur le serveur de production. Vous devrez ensuite, comme pour les librairies symfony, ajouter un lien symbolique afin de permettre à symfony d'utiliser Pake :

$ ln -sf /home/myaccount/pake/lib lib/pake

Vous devriez alors vous retrouver avec une arborescence semblable à la suivante :

/home/myaccount/
  pake/
    lib/      
  symfony/
    lib/
    data/
  askeet/
    apps/
      frontend/
    batch/
    cache/
    config/
    data/
      symfony/ -> /home/myaccount/symfony/data
    doc/
    lib/
      symfony/ -> /home/myaccount/symfony/lib
      pake     -> /home/myaccount/pake/data
    log/
    test/
    web/

Pour appeler la commande clear-cache de symfony, vous devez alors taper :

$ cd /home/myaccount/askeet/
$ php lib/pake/bin/pake.php -f lib/symfony/data/symfony/bin/pakefile.php clear-cache

Vous pouvez également créer un fichier, nommé symfony, sous home/myaccount/askeet/ contenant le code suivant:

#!/bin/sh

php lib/pake/bin/pake.php -f lib/symfony/data/symfony/bin/pakefile.php $@

Pour nettoyer le cache, il ne vous reste alors plus qu'à taper un bon vieux :

$ symfony clear-cache

Accéder aux commandes symfony par le Web

Si vous voulez profiter des avantages de pake sans la ligne de commande, vous pouvez également créer un accès Web pour la commande clear-cache.

Vous pouvez ainsi créer le fichier webpake.php suivant dans votre répertoire /home/myaccount/askeet/web/ :

<?php

// nous sommes dans le répertoire web/, nous devons donc remonter d'un niveau pour accéder à la racine du projet
chdir(dirname(__FILE__).DIRECTORY_SEPARATOR.'..');

include_once('/lib/symfony/pake/bin/pake.php');

$pake = pakeApp::get_instance();
try
{
  $ret = $pake->run('/data/symfony/bin/pakefile.php', 'clear-cache');
}
catch (pakeException $e)
{
  print "<strong>ERROR</strong>: ".$e->getMessage();
}

?>

Nettoyer le cache reviendra ensuite à accéder à la page :

http://myaskeetprodserver.com/webpake.php

NOTE : Vous devez être conscients qu'en donnant accès par le Web à des outils d'administration, vous pouvez créer une brèche de sécurité dans votre site.

Mettre à jour votre application

There will be times in the life of your project when you need to switch between two versions of an application. It can be in order to correct bugs, or to upload new features. You can also be faced with the problem of switching between two versions of the database. If you follow a few good practices, these actions will prove easy and harmless. Show unavailability notice

Between the moment when you start the data transfer and the moment you clear the cache (if you modify the configuration or the data model), there are sometimes more than a few seconds of delay. You must plan to display an unavailability notice for users trying to browse the site at that very moment.

In the application settings.yml, define the unavailable_module and unavailable_action settings:

all: .settings: unavailable_module: content unavailable_action: unavailable

Create an empty content/unavailable action and a unavailableSuccess.php template:

// askeet/apps/frontend/modules/content/actions/actions.class.php public function executeUnavailable() { $this->setTitle('askeet! » maintenance'); }

// askeet/apps/frontend/modules/content/templates/unavailableSuccess.php

Askeet: Site maintenance

The askeet website is currently being updated.

Please try again in a few minutes.

The askeet team

Now each time that you want to make your application unavailable, just change the available setting:

all:

.settings:

available:              off

Don't forget that for a configuration change to be taken into account in production, you need to clear the cache.

: The fact that the whole application can be turned off with only a single parameter is possible because symfony applications use a single entry point, the front web controller. You will find more information about it in the controller page of the symfony book.

Use two versions of your application

A good way to avoid unavailability is to have the project root folder configured as a symlink. For instance, imagine that you are currently using the version 123 of your application, and that you want to switch to the version 134. If your web server root is set to /home/myaccount/askeet/web/ and that the production folder looks like that:

/home/myaccount/ pake/ lib/ symfony/ lib/ data/ askeet/ -> /home/production/askeet.123/ askeet.123/ askeet.134/

Then you can instantly switch between the two versions by changing the symlink:

$ ln -sf /home/myaccount/askeet/ /home/myaccount/askeet.134/

The users will see no interruption, and yet all the files used after the change of the symlink will be the ones of the new release. If, in addition, you emptied the cache/ folder of your release 134, you don't even need to launch a clear-cache after switching applications. Switching databases

You can extrapolate that technique to switching databases. Remember that the address of the database used by your application is defined in the databases.yml configuration file. If you create a copy of the database with a new name, say askeet.134, you just need to write in the askeet.134/apps/frontend/config/databases.yml:

all: propel: class: sfPropelDatabase param: phptype: mysql hostspec: localhost database: askeet.134 username: myuser password: mypassword compat_assoc_lower: true compat_rtrim_string: true

As the databases.yml will be switched as the same time as the application itself, your askeet will instantly start querying the new database.

This technique is especially useful if your application has a big traffic and if you can't afford any service interruption. See you Tomorrow

Synchronization is often a big issue for high traffic websites, but thanks to the file structure of the symfony projects, it should not create any problem for askeet.

Tomorrow, we will talk about the way to adapt askeet to other languages. The patient speakers call it internationalization, the others find it more convenient to talk about i18n. Symfony has built-in support for multilingual sites, so that should not be a big deal.

You can still post your questions and suggestions in the askeet forum. And did you try to ask one in the brand new askeet website?