Préparer une application
Même si l’on code massivement avec des langages de script pour ne pas passer par la case compilation, il y a forcément une étape de préparation avant de pouvoir livrer une application à partir de ses sources : télécharger les modules et compiler les potentiels binding en C, mais surtout gérer tout le bazar lié aux assets : JavaScript et CSS.
Cette étape de préparation avant déploiement porte en anglais le nom poétique de baking : on cuit le pain avant de le livrer.
Il n’y a aucun intérêt à réaliser cette étape sur le serveur de production qui a surement mieux à faire : c’est long, ça requière des outils plus ou moins louches, et si l’application est distribuée, il faut recommencer sur chaque instance.
Préparer Isso
Voici un exemple commenté de préparation et déploiement de Isso, un clone libre et local de Disqus, qui permet d’embarquer des commentaires depuis du JavaScript, sur un site qui peut même être statique. Le serveur est en Python, et il fournit du JavaScript à embarquer dans ses pages HTML.
Pour ne pas pourrir ma machine en installant des outils bizarres, j’utilise des containers Docker à usage unique. Pour avoir un build sans trop de répétitions, j’utilise un simple Makefile. Oui, Makefile est vieux et moche, mais pas plus que bash, et il est un standard de fait. Pour des taches de tailles raisonnables, il reste tout à fait pertinent.
En montant un dossier local dans le container, le résultat du traitement se retrouvera dans ce dossier. La source et le résultat sont locaux, le traitement distant.
Cerise sur le gâteau, grâce à boot2docker,l’action lancée depuis un Mac, va faire travailler un Linux, et surtout, produire du contenu pour Linux.
Pour éviter toutes surprises, je n’utilise que des images officielles de Docker, forcément basé sur Debian (et Wheezy, si possible).
Cuire le Python
Isso est packagé sur Pypi : il s’installe simplement avec pip. Je sais installer python, mais comme la vie est courte, autant utiliser python:2-wheezy.
Makefile pense à l’envers, en pensant prérequis et dépendances. Pour avoir l’application Isso, j’ai besoin d’un python dans un virtualenv, qui a besoin d’un dossier app. Ce qui donne :
app/bin/isso: app/bin/python
docker run --volume=`pwd`/app:/app --rm --workdir=/app python:2-wheezy /app/bin/pip install isso
app/bin/python: app
docker run --volume=`pwd`/app:/app --rm --workdir=/app python:2-wheezy virtualenv .
app:
mkdir app
Comme je suis radin, j’efface (—rm) le container dès qu’il a exécuté son action.
Cuire le JavaScript
Le JavaScript, de nos jours, utilise plus de bazars que du C++ pour être utilisable. Isso est sobre, il se contente de Bower pour aller chercher les bibliothèques et leurs dépendances, Uglify pour compacter, et on échappe à Grunt, un Makefile est utilisé à la place.
js: src/isso/js/embed.js
docker run --volume=`pwd`/src:/src --rm --workdir=/src node:wheezy sh -c 'npm install -g bower requirejs jade && make init && make js'
echo "Your minified javascript files are here:"
find src/isso/js -name *.min.js
src/isso/js/embed.js: src
git clone https://github.com/posativ/isso.git src/
src:
mkdir src
Même tactique, une image jetable avec nodejs : node:wheezy est utilisée. Petite astuce, “docker run” n’accepte qu’une seule commande en argument, du coup, il faut passer par un sh -c 'pim && pam && poum'
Livrer le gâteau
La cuisson s’est faite dans des containers, mais le résultat est à chaque fois un simple dossier, tout ce qu’il y a de plus traditionnel.
Il est possible de déployer l’application ainsi, avec un rsync
et un supervisor.
J’ai fait le choix de la déployer avec Docker. Le Dockerfile utilisé est minimaliste.
FROM python:2-wheezy
COPY app /app
VOLUME /conf
WORKDIR /app
EXPOSE 1234
CMD ["/app/bin/isso", "-c", "/conf/isso.conf", "run"]
Le dossier contenant le fichier de configuration est réclamé, par contre, l’application est embarquée.
Pour configurer tout ça, un docker-compose.yml qui va utiliser le Dockerfile.
---
isso:
build: . # Dans le même dossier
# Aucun privilège
cap_drop:
- ALL
ports:
- "1234:1234"
volumes:
- "conf:/conf" # Pour la configuration
- "data:/data" # Pour la base de données
La configuration isso est tout aussi simple
[general]
dbpath = /data/comments.db
host = https://example.tld/
[server]
listen = http://0.0.0.0:1234/
Le dossier data monté dans compose est utilisé pour accueillir la base sqlite, et le serveur écoute bien le port 1234.
Il faut ensuite tricoter les urls pour avoir le site web et Isso.
Le site en production n’aura aucune séquelle de son installation, pas de nodejs, pas de choses qui trainent, juste une Wheezy spartiate et une application.
Tout le code est disponible sur github, sous Licence BSD.