Mise en perspective du principe KISS : Mettre à jour une application web

J’ai décidé de m’interroger sur ma façon de mettre à jour une application web. Il y a eu une réflexion intéressante qui a été publiée par Blogus Librus sur le principe KISS.

Par exemple j’ai l’application web Shaarli dans le dossier /var/www de mon server@home, comment je fais pour la mettre à jour ?

Je vais vous présenter ma progression. Chacun pourra ainsi décider et voir où il se situe : Plutôt côté KISS donc simple ou plutôt côté élégant mais complexe. Je trouve que c’est une bonne mise en perspective du billet de Blogus Librus.

Au commencement

Ainsi donc au commencement pour mettre à jour Shaarli dans /var/www je faisais comme ci-dessous. Ça doit être la méthode employée par la majorité d’entre nous à quelques détails près (cd /tmp, cp remplacé par mv). C’est simple, c’est KISS. En 5 lignes.

cd /tmp && wget https://github.com/shaarli/Shaarli/archive/stable.tar.gz # On se place dans le dossier /tmp puis on télécharge la dernière version stable de Shaarli
tar -xzf *.tar.gz # On se trouve donc dans le dossier /tmp, on extrait le contenu de l'archive. L’intérêt du dossier /tmp est qu'il sera purgé à l'extinction et que vous ne devriez avoir qu'une seule archive .tar.gz dedans simplifiant alors la ligne de commande
cp -R /tmp/Shaarli-stable/* /var/www/shaarli # On copie récursivement le contenu du dossier (extrait de l'archive) dans le dossier shaarli de notre serveur web
chown -R www-data:www-data /var/www/shaarli && chmod -R 755 /var/www/shaarli # On remet les droits comme il faut récursivement avec les commandes chmod et chown
systemctl restart apache2 # On redémarre le service apache2 afin que les modifications soient bien prises en compte

0.1

En 4 lignes. Légère amélioration mais on économise une ligne de commande à saisir. On extrait directement le contenu de l’archive dans /var/www/shaarli (et non pas dans /tmp), voir ici (en Anglais) pour plus d’explications.

cd /tmp && wget https://github.com/shaarli/Shaarli/archive/stable.tar.gz # Pas de changement par rapport à la version précédente
tar -xzf *.tar.gz -C /var/www/shaarli --strip-components=1 # On se trouve dans le dossier /tmp, on extrait directement le contenu de l'archive dans /var/www/shaarli. On gagne une ligne de commande
chown -R www-data:www-data /var/www/shaarli && chmod -R 755 /var/www/shaarli # Pas de changement par rapport à la version précédente
systemctl restart apache2 # Pas de changement par rapport à la version précédente

0.2

Toujours 4 lignes mais on améliore considérablement le processus :
Ligne 1 : On sauvegarde le dossier de notre application web avant de la mettre à jour
Ligne 2 : La dernière version de Shaarli est envoyée sur la sortie standard (par wget), via le pipe | tar reçoit l’archive sur l’entrée standard et extrait directement le contenu dans le dossier /var/www/shaarli. Ainsi on n’a même pas le fichier stable.tar.gz qui apparaît sur le disque dur
Ligne 4 : Tant qu’à redémarrer les services autant ajouter php5-fpm que tout le monde devrait utiliser avec apache2 maintenant

cp -a /var/www/shaarli{,.bak}, on utilise l’option -a qui fait principalement deux choses à savoir une copie récursive et conserver les attributs (permissions) des fichiers. {,.bak} est une manière élégante de faire la même chose que cp -a /var/www/shaarli /var/www/shaarli.bak.

wget -qO -, on utilise wget en mode quiet (silencieux) avec l’option -q. La difficulté se situe sur O -, cela signifie qu’on envoie le fichier vers la sortie standard (d’après le man wget à propos de l’option -O : « If – is used as file, documents will be printed to standard output »).

cp -a /var/www/shaarli{,.bak} # On sauvegarde le dossier de notre application web avant de la mettre à jour, on aura ainsi un dossier /var/www/shaarli.bak pour revenir en arrière en cas de problèmes
wget -qO - https://github.com/shaarli/Shaarli/archive/stable.tar.gz | tar -xzf - -C /var/www/shaarli --strip-components=1 # On télécharge la dernière version stable de Shaarli et on l'extrait directement via un pipe dans le dossier /var/www/shaarli
chown -R www-data:www-data /var/www/shaarli && chmod -R 755 /var/www/shaarli # Pas de changement par rapport à la version précédente
systemctl restart apache2 php5-fpm # On redémarre les services apache2 et php5-fpm afin que les modifications soient bien prises en compte

1.0

On arrive à la méthode élégante mais complexe que j’ai décidé d’utiliser pour mettre à jour une application web.

On a juste modifié tar -xzf - -C /var/www/shaarli --strip-components=1 en tar -xzC /var/www/shaarli --strip-components=1. Pour rappel l’option -f signifie : utilise le fichier d’archive ou le périphérique suivant.

La première manière de faire peut paraître plus complexe mais elle est plus compréhensible. f - signifie que le fichier d’archive à extraire arrive via stdin (flux d’entrée standard). Dans la seconde manière de faire on n’a pas l’option -f, il est sous-entendu qu’on prend comme fichier d’archive celui qui arrive via stdin.

Elle est complète, élégante, courte : On sauvegarde le dossier de l’application web avant de la mettre à jour, on extrait directement le contenu de l’archive dans /var/www/shaarli (sans même que le fichier stable.tar.gz apparaisse sur le disque dur) enfin on remet les droits au propre et on redémarre les services.

cp -a /var/www/shaarli{,.bak} # Pas de changement par rapport à la version précédente
wget -qO - https://github.com/shaarli/Shaarli/archive/stable.tar.gz | tar -xzC /var/www/shaarli --strip-components=1 # On télécharge la dernière version stable de Shaarli et on l'extrait directement via un pipe dans le dossier /var/www/shaarli
chown -R www-data:www-data /var/www/shaarli && chmod -R 755 /var/www/shaarli # Pas de changement par rapport à la version précédente
systemctl restart apache2 php5-fpm # Pas de changement par rapport à la version précédente

Déjà 17 avis pertinents dans Mise en perspective du principe KISS : Mettre à jour une application web

  • ianux
    Inutile de redémarrer Apache si on ne modifie rien dans /etc/apache2 (et encore, un simple reload suffit la plupart du temps). Pareil pour php-fpm dont la conf ne bouge pas non plus. La mise à jour de la conf de Shaarli se fera en temps réel lors de l’accès au site.
  • Xavier C.
    Salut,
    Tout d’abord un redémarrage de Apache n’est pas nécessaire, tu peux supprimer cette étape.
    Ensuite, petite optimisation, au lieu de faire chown -R www-data:www-data tu peux juste mettre chown www-data: ;)
    Avec un chmod 750 au passage.

    Après shaarli est un mauvais exemple puisque tu peux le mettre à jour avec git pull tout simplement.

    Une autre méthode « élégante » mais pas toujours possible est d’utiliser des symlink current ce qui permet de basculer d’une version à l’autre en un clin d’œil, mais il faut que les deux versions pointent sur mes mêmes données donc il faut modifier un peu les arbo.

  • Bruno
    Oui enfin, même un chmod -R 750 sur un dossier web , cela reste assez sale… Il n’y a aucune raison de donner les droits d’exécution sur tous les fichiers.
  • Bruno
    Il faudrait déjà savoir pourquoi tu exécutes une commande chmod. Qu’est-ce qui ne va pas dans les droits d’accès après décompression de l’archive ?

    De manière générale toute commande chmod 7 ou 5 (c’est à dire qui donne les droits de lecture et d’exécution) en mode récursif est généralement un grosse bêtise. J’ai souvent constaté que cette commande était utilisé pour donner un droit d’accès sur les dossiers sans avoir conscience que cela agissait aussi sur les fichiers en leur donnant un droit d’exécution !
    Je préconise d’ailleurs d’essayer de ne jamais utiliser la commande chmod en mode octal.

    Si j’avais un conseil à donner pour modifier les droits, je dirais qu’il faut toujours les établir à minima. Dans ce cas, le minimum est un accès en lecture pour le service qui exécute les scripts php. Puisque c’est ww-data chez toi et qu’il est propriétaire des fichiers r-x—— sur les dossiers (500) et r——–(400) sur les fichiers seraient suffisants. Mais une application web a souvent besoin d’écrire dans certains dossiers, voir de modifier certains fichiers, il faudrait donc lui donner les droits d’écriture sur ceux_ci. Dans la pratique, et puisque www-data est propriétaire et groupe, on peut très bien avoir rwxrwx— (770) sur les dossiers et rw-rw—- (660) sur les fichiers.

    Je te renvoie a man chmod pour savoir comment ajouter/enlever des droits (chmod -R -x /truc pour enlever le droit d’exécution, chmod -R +X /truc pour placer le droit d’accès sur les dossiers, par exemple).

    Puisque l’on est dans la gestion des droits, je trouve dommage d’utiliser php-fpm sans se servir des pools pour gérer de manière plus sécurisée les utilisateurs et groupes : un utilisateur différent pour chaque site/application web.
    Admettons qu’il y ait une faille de sécurité dans une de tes application hébergé qui permettent l’injection des scripts (malheureusement c’est assez fréquent). Le script malveillant s’exécutera sous l’utilisateur www-data, et donc tout ce qui est accessible à cet utilisateur pourra être compromis et utilisé pour compromettre le serveur.

  • poulpe
    +1 pour le symlink vers la version ‘en production’ qui permet de faire un upgrade atomique (pas de coupure de service, pas d’incohérences possibles entre des fichiers de plusieurs versions simultanées, etc.).
  • frague
    J’ai une approche assez différente. Je suis développeur Web dans une collectivité, et pour déployer mes appli je procède de la façon suivante:

    $ls /var/www:
    appli.example.com/src > /home//prod/appli.example.com/current > 1.2.3
    appli.example.com/static
    appli.example.com/media
    appli.example.com/log

    $ ls /home//prod/prod/appli.example.com/
    1.0.0
    1.0.1

    1.2.1
    1.2.2
    1.2.3
    1.2.4
    current -> 1.2.3

    J’utilise au maximum les possibilités des liens symboliques pour déployer les applications :
    * Le dossier /var/www//src est un lien symbolique vers ‘current » dans /home//prod//current, qui est lui même un lien symbolique vers le dossier 1.2.3, qui est (daan mon cas) l’export d’un tag svn, mais qui pourrais être une release GIT

    Pour faire la mise à jour:
    $ cd /home//prod/ && svn export /tags/1.2.3
    $ rm current && ln -s 1.2.3 current && sudo systemclt reload apache2
    et basta…
    Ça me permet de garder toutes les releases sur mon serveur, et de revenir en arrière si j’ai cassé quelque chose.

  • Charpy
    Et bien moi qui suis loin d’être un pro, je me farci encore le download en local de la dernière version, la décompression et l’envoi fichier par fichier sur le serveur par http://FTP... C’est grave doc’? :x
  • AkhThoT
    J’ai l’impression moi aussi que de plus en plus on se complique la vie avec des outils supplémentaires fait pour se faciliter la vie.

    On devient dépendant des ces outils ‘facilitateur’, car on oublie comment faire sans et là typiquement on explique comment faire avec mais on explique plus ce qui est fait fondamentalement et donc comment faire en se passant de l’outil.

    En plus je trouve complètement contraire au principe KISS cette démarche.

    Tapez des lignes de commandes bêtement parce que l’on a trouvé quelqu’un sur le net qui fait comme ça, je peux le comprendre d’une personne qui ne veut s’investir ni en temps, ni en compréhension, mais d’autres seront découragés avec des approches pareilles.

Les commentaires sont fermés.