fabric – Sam & Max http://sametmax.com Du code, du cul Wed, 23 Dec 2020 13:35:02 +0000 en-US hourly 1 https://wordpress.org/?v=4.9.7 32490438 La stack techno qu’on utilise pour faire un site Web, et pourquoi http://sametmax.com/la-stack-techno-quon-utilise-pour-faire-un-site-web-et-pourquoi/ http://sametmax.com/la-stack-techno-quon-utilise-pour-faire-un-site-web-et-pourquoi/#comments Mon, 11 Nov 2013 06:40:38 +0000 http://sametmax.com/?p=7648 Une stack techno n’est pas une référence. Il n’y a pas de combo absolu qui rox absolument tout, c’est une question de contexte technique, financier, humain…

Mais c’est vrai que ça aide bien d’avoir sous les yeux les pratiques des autres.

Je ne vais pas expliquer pourquoi Python, je l’ai déjà fait.

Commençons plutôt par la partie purement Web, pour laquelle on utilise Django, le framework Web Python.

Max et moi avons tout deux fait du PHP avant, j’ai tâté des frameworks internes, du Symfony et plus tard du Zope. J’ai regardé du côté de Pyramid et de ses prédécesseurs, et Django est celui qui me plaît le plus. J’ai juste un peu forcé la main à Max :-)

Car oui, le framework a été avant tout un choix de goût.

Ce n’est pas un choix de performances : le framework n’a aucun impact dessus. Aucun. Les architectures ont un impact. Le framework, non. Votre bottleneck sera sur les IO, pas sur le CPU. Le choix de technos asynchrones peut avoir un impact, mais ce n’est pas une question de framework. Tornado, Twisted ou NodeJS, on s’en fout.

Donc Django, essentiellement parce qu’il me plait. Et il me plaît pour ces raisons :

  • Il y a un bon équilibre entre découplage et intégration. En général c’est soit très découplé et mal intégré, soit très bien intégré et très couplé.
  • C’est bien foutu et bien documenté. Et c’est stable. Vraiment très stable. Les core devs sont hyper sérieux.
  • C’est très versatile et ça peut faire plein de trucs out of the box, petits comme gros.
  • C’est assez facile à apprendre. Ça reste un framework, donc ce n’est pas la plus simple des démarches, mais dans le royaume des frameworks de cette taille, ça reste vraiment le plus simple.
  • La communauté est fantastique : il y a des centaines d’apps qui couvrent pratiquement tous les besoins.
  • Et bien entendu, c’est en Python.

En terme de base de données, on a fait du MySQL pendant longtemps. Ça a plutôt bien marché. Maintenant je commence mes nouveaux projets avec PostGres, qui est plus solide. Parfois je fais juste du Sqlite, parce que ça suffit.

Pas de NoSQL. Après plusieurs expériences avec MongoDB et CouchDB, je n’ai pas été convaincu que les bénéfices dépassaient le coût. Il faudrait un article complet là-dessus (qu’on m’a d’ailleurs demandé).

Question OS. c’est du CentOS avec Max (il a plus l’habitude) ou du Ubuntu Server pour mes autres projets. Je reste sur les LTS. Ce n’est pas un choix très réfléchi, c’est surtout par habitude.

Pas de machine virtuelle. On a essayé, sans y trouver un grand intérêt :

  • Il faut quand même faire des scripts de migration, donc autant s’en servir pour le déploiement.
  • On perd en perfs.
  • Les erreurs liées au mal-fonctionnement d’une VM sont absolument indébuggables.
  • Si on ne fait pas la VM soit-même, il faut mettre ses couilles dans les mains d’un prestataire de service. J’ai horreur de ça.
  • Trouver des gens avec la compétence pour gérer une VM, c’est difficile. Un script de déploiement, c’est du code que tout dev saura déjà lire. Par extension ça veut dire que je m’y replonge facilement des semaines plus tard.

Et donc pour le déploiement, j’utilise fabric, avec fabtools.

Ce n’est pas la solution la plus efficace, d’autant que ça limite à Python 2.7, mais c’est la plus simple. C’est juste du code Python. N’importe qui peut comprendre le déploiement en 15 minutes. Ça se modifie vite, s’adapte facilement.

Il faut comprendre qu’on a jamais plus d’une dizaine de serveurs pour un projet, ces choix sont donc faits en fonction de cela. Il va sans dire que si vous gérez un parc de centaines de machines, ça ne sera pas du tout le même choix technique. Peut être que Chef ou des VM seront alors carrément plus intéressants. Peut être que le NoSQL et sa capacité au scaling sera bien plus rentable.

Il ne s’agit pas de décrier les technos que nous n’utilisons pas. Il s’agit juste de dire, voilà les choix que nous avons faits, dans tel contexte, pour telles (bonnes ou mauvaises) raisons.

Durant les dernières années, on a ajouté Redis à notre stack. C’est un outil fantastique qui sert à tout : de la base de données pour les trucs simples (il y a des fois ou un schéma est overkill) à la solution de caching. C’est ce qu’on a de plus proche du NoSQL.

L’outil est tellement simple à installer (vraiment le degré zero de la maintenance, c’est beau) et à utiliser que ça ne vaut juste pas le coup de s’en priver.

Du coup, plus de memcache. Toutes les grosses requêtes sont sauvegardées dans Redis, dès qu’on fait un script qui a besoin de persistance temporaire, Redis, pour communiquer entre plusieurs process, Redis, pour toutes les opérations qui ont besoin de grosses perfs comme les stats, Redis. Vive Redis.

D’ailleurs on utilise Redis aussi comme broker pour notre gestionnaire de queues et de taches : celery. Si vous pythonez, je vous recommande chaudement celery pour toutes les tâches en background, les crawlers, les chaînes de process, etc.

On a aussi du moteur de recherche. Là on tape dans du Solr (avec haystack). C’est très puissant, en tout cas syntaxiquement car ça ne fait pas de sémantique. Ne vous attendez donc pas à rattraper Google. Mais c’est aussi méga chiant à configurer et très lourd. Je pense qu’un jour on va migrer sur ElasticSearch, mais c’est pas la priorité. Don’t fix what ain’t broken.

Devant tout ça on a Nginx. Comme beaucoup on a fait Apache => Cherokee => lighttp => nginx. Et franchement, je ne reviendrai jamais en arrière : plus léger, plus rapide, plus facile à installer et à configurer, plus versatile. Nginx fait tout, et mieux.

En proxy on a du gunicorn. Parce qu’on avait la flemme de configurer uwsgi et qu’on a pris l’habitude.

Après on utilise plein de libs, de petits outils, etc. Mais ça c’est le gros de notre archi.

]]>
http://sametmax.com/la-stack-techno-quon-utilise-pour-faire-un-site-web-et-pourquoi/feed/ 33 7648
Appeler une fonction fabric, hors d’un fichier fabfile http://sametmax.com/appeler-une-fonction-fabric-hors-dun-fichier-fabfile/ http://sametmax.com/appeler-une-fonction-fabric-hors-dun-fichier-fabfile/#comments Sun, 14 Apr 2013 17:57:27 +0000 http://sametmax.com/?p=5660 C’est con mais c’est bon à savoir : si vous avez une un tâche fabric, vous pouvez tout à fait l’appeler en dehors de fabfile dans n’importe quel script Python.

Il suffit de faire dans ce script :

from fabric.api import run, execute, env
from fabfile import la_tache

execute(la_tache)

Et on peut changer n’importe paramètre en le passant en keyword à execute. Par exemple pour changer l’host :

hosts = ['user@serveurdistant.com', ...]
execute(la_tache, hosts=[host])

]]>
http://sametmax.com/appeler-une-fonction-fabric-hors-dun-fichier-fabfile/feed/ 13 5660
Travailler moins pour gagner plus, en 15 minutes avec Python fabric http://sametmax.com/travailler-moins-pour-gagner-plus-en-15-minutes-avec-python-fabric/ http://sametmax.com/travailler-moins-pour-gagner-plus-en-15-minutes-avec-python-fabric/#comments Wed, 22 Feb 2012 01:09:47 +0000 http://sametmax.com/?p=190 fabric. Un jour, après avoir chassé un bug des heures dû à une erreur sur un process de mise en ligne, je me suis motivé. Bonne surprise, ça m'a pris 30 minutes. Avec cet cet article ça vous en prendra 15.]]> Apprendre encore un nouvel outil, c’est du temps et de l’énergie. Du coup j’ai longtemps ignoré l’outil automatique de déploiement fabric.

On vit très bien sans, mais un jour, après avoir chassé un bug des heures qui n’était dû qu’à une erreur de ma part sur un process répétitif et ennuyeux de mise en ligne, je me suis motivé. Bonne surprise, ça m’a pris 30 minutes. Et avec cet article, ça vous en prendra 15.

Avant

Fabric est un outil qui vous permet d’écrire, en Python, un script de déploiement ; c’est à dire d’automatiser la mise en ligne d’une nouvelle version de votre site.

Comme ça, ça n’a pas l’air d’être quelque chose qu’on utilise souvent, mais pourtant, quand vous corrigez un simple bug dans une requête AJAX sur un projet Django sauvegardé dans Git, voilà ce que vous devez faire:

  1. git pull remote branch (pour s’assurer que personne n’a modifié le code entre temps)
  2. git push remote branch (pour sauvegarder votre code tout frais)
  3. ssh user@host (pour aller sur le serveur distant)
  4. cd /path/to/project
  5. workon virtualenv
  6. ./manage.py collectstatic (pour que le nouveau fichier Javascript soit mis en ligne)
  7. supervisorctl -c settings/prod_supervisor.ini restart all (pour redémarrer les workers et qu’ils prennent en compte les modifications du code Python)
À un moment, vous allez vous planter dans une étape, tellement c’est ennuyeux et répétitif.

Après

Comme d’hab, on commence par un coup de pip:

pip install fabric

Et dans un fichier fabfile.py à la racine de votre projet en local:

from fabric.api import local, run, cd, env, prefix

REMOTE_WORKING_DIR = '/path/to/project'

env.hosts = ['siteweb.com']
env.user = 'username'

def push(branch='master', remote='origin', runlocal=True):
    if runlocal:
        # lance la commande en local
        local("git push %s %s" % (remote, branch))
    else:
        # lance la commande sur les serveurs de la liste eng.hosts
        run("git push %s %s" % (remote, branch))

def pull(branch='master', remote='origin', runlocal=True):
    if runlocal:
        local("git pull %s %s" % (remote, branch))
    else:
        run("git pull %s %s" % (remote, branch))

def sync(branch='master', remote='origin', runlocal=True):
    pull(branch, remote, runlocal)
    push(branch, remote, runlocal)

def deploy(branch='master', remote='origin'):
    # execute toutes les commandes dans ce dossier
    with cd(REMOTE_WORKING_DIR):
        # excute toutes les commandes avec celle-ci avant
        with prefix('workon virtualenv'):
            pull(branch, remote, False)
            run("./manage.py collectstatic --noinput")
            run("supervisorctl -c settings/prod_supervisor.ini restart all")

Et voilà du temps de sauvé, et des erreurs évitées pour un investissement vraiment minimal.

Synchroniser son code avec le reste de l’équipe: fab sync
Déployer le code en production: fab deploy
Les deux: fab sync deploy

Et ce n’est qu’une intro. On peut faire des choses biens plus avancées, notamment gérer plusieurs type de déploiements, de serveurs, etc.

Notez qu’on pourrait faire le faire en bash sans avoir à installer fabric, mais un script bash, c’est tellement laborieux à faire évoluer…

]]>
http://sametmax.com/travailler-moins-pour-gagner-plus-en-15-minutes-avec-python-fabric/feed/ 6 190