diff --git a/README.md b/README.md
index bfe1045f844d3379dec98f3b91cf827ccd843bc2..cb63e56b7b96cf465f726a3ced0605464e67808e 100644
--- a/README.md
+++ b/README.md
@@ -1,14 +1,14 @@
 # Dockerfiles de Picasoft
 
-Ce dépôt centralise les Dockerfiles et autre ressources utilisées pour construire **et** déployer les images Docker tournant en production sur l'infrastructure de Picasoft.
+**Lisez cette documentation avant toute chose : elle fait office de référence générale et contient des informations supplémentaires par rapport aux README des dossiers :D**
 
-Certains services ne respectent pas encore la structure de ce dépôt (exemple : `nextcloud-docker`, ou Traefik qui reste géré uniquement sur les VM) : ils seront migrés prochainement.
+Ce dépôt centralise les Dockerfiles et autre ressources utilisées pour construire **et** déployer les images Docker tournant en production sur l'infrastructure de Picasoft.
 
 ## Philosophie
 
 Historiquement, Picasoft procède de la manière suivante :
 * Construire les images Docker à partir de Dockerfiles sur une machine quelconque, puis les pousser manuellement sur un registre privé.
-* Gérer un Docker Compose global par VM, qui contient la configuration et les secrets.
+* Gérer un fichier Compose global par machine, qui contient la configuration et les secrets.
 
 Cette approche pose plusieurs problèmes. Comment savoir ce qu'il y a dans une image, si on perd le Dockerfile ? Quel Dockerfile correspond à quelle version de l'image ? Si on perd l'accès à la machine, comment récupérer la configuration, remonter rapidement le service ? Comment versionner les changements de configuration ? Revenir à la version d'il y a deux semaines ?
 
@@ -22,7 +22,9 @@ Son objectif secondaire est de pouvoir revenir à l'état antérieur d'un servic
 * Checkout un commit quelconque
 * Lancer le service normalement
 
-Mises à part les données à proprement parler du service, il n'y a donc aucune différence entre un service lancé sur une de nos machines et un service lancé à partir de ce dépôt sur une machine virtuelle quelconque, ce qui s'inscrit dans la philosophie Docker.
+Son dernier objectif est de permettre de rendre publics nos fichiers Compose et la configuration, sans exposer les secrets (mots de passe, etc).
+
+Mises à part les données à proprement parler du service, il n'y a donc aucune différence entre un service lancé sur une de nos machines et un service lancé à partir de ce dépôt sur une machine quelconque, ce qui s'inscrit dans la philosophie Docker.
 
 ## Contenu du dépôt
 
@@ -30,29 +32,27 @@ Le dépôt est organisé en dossiers. Chaque dossier correspond à un *service*
 
 Ainsi, chaque dossier de ce dépôt contiendra, selon les situations :
 
-* Zéro, un ou plusieurs `Dockerfile` permettant de construire les images personnalisées pour Picasoft,
+* Zéro, un ou plusieurs `Dockerfile` permettant de construire des images personnalisées pour Picasoft,
 * Un fichier `docker-compose.yml` permettant de lancer le service,
 * Si possible, un ou des fichiers de configuration permettant de personnaliser le service selon nos besoins,
-* Un fichier d'exemple de secrets (mot de passe...) nécessaire au lancement du service,
+* Un fichier d'exemple de secrets (mots de passe...) nécessaires au lancement du service,
 * Un `README.md` résumant les paramètres modifiables sur le dépôt, les mécanismes pour en rajouter, etc,
 * Pour les images maison, un `CHANGELOG.md` résumant les modifications faites au fil des version.
 
-Il n'y a pas de Docker Compose global : chaque service a son propre Docker Compose, lui permettant d'être déployé indépendamment des autres.
+Chaque service a son propre fichier Compose, lui permettant d'être déployé indépendamment des autres.
 
-Un exemple concret peut être trouvé au niveau de [pica-mattermost](./pica-mattermost) ou [pica-etherpad](./pica-etherpad).
+Des exemples concrets peuvent être trouvés au niveau de [pica-mattermost](./pica-mattermost) ou [pica-etherpad](./pica-etherpad).
 
-## Guides d'utilisation
+## Guides
 
 ### Lancer ou redémarrer un service sur une machine de Picasoft
 
-Lire [la documentation de déploiement et de maintenance]().
+Lire [la documentation de déploiement et de maintenance](./doc/launch_service.md).
 
 ### Mettre à jour un service ou sa configuration
 
-Lire [la documentation de mise à jour des services]().
+Lire [la documentation de mise à jour des services](./doc/update_and_test.md).
 
 ### Mettre en place un nouveau service
 
-Lire [la documentation de versionnage d'un nouveau service]() et [les bonnes pratiques pour Docker]().
-
-Un dossier [template](./template) prêt à copier est aussi disponible.
+Lire [la documentation de versionnage d'un nouveau service](./new_service.md) et [les bonnes pratiques pour Docker](./doc/guide_bonnes_pratiques.md).
diff --git a/doc/guide_bonnes_pratiques.md b/doc/guide_bonnes_pratiques.md
index f03a8036b974e7e8b64e95f96ed3101cd8f383be..a2dc03edfe86eb985c50a2f2c5ad49fda7552716 100644
--- a/doc/guide_bonnes_pratiques.md
+++ b/doc/guide_bonnes_pratiques.md
@@ -18,13 +18,7 @@ Il y a plusieurs cas.
 
 ### Je veux faire tourner un service existant, tel quel
 
-Si un service existant a une image Docker officielle, référencée sur le Docker Hub, alors on créera un Dockerfile *dummy*, ne contenant qu'une instruction `FROM`. Exemple :
-
-```Dockerfile
-FROM grafana:4.8
-```
-
-Le reste est identique : on crée notre `docker-compose.yml`, notre `README.md`, notre `clair-whitelist.yml`, et les fichiers de secrets d'exemple.
+Si un service existant a une image Docker officielle, référencée sur le Docker Hub, et qu'elle nous suffit, on s'en servira tel quel dans le `docker-compose.yml`.
 
 ### Je veux customiser un service existant
 
diff --git a/doc/guide_deploiement.md b/doc/guide_deploiement.md
deleted file mode 100644
index 23889a44ef34274d9a080dae6c76d8178622f771..0000000000000000000000000000000000000000
--- a/doc/guide_deploiement.md
+++ /dev/null
@@ -1,135 +0,0 @@
-# Déployer un service
-
-Dès lors que la chaîne d'intégration a construit une image Docker, il est possible de tester et de déployer le service concerné.
-
-## Test du service
-
-Avant de mettre un service en production, il faut vérifier que le service se lance bien comme prévu. Pour ce faire, on se rend sur une machine virtuelle de test (exemple : `pica01-test.picasoft.net`) et on se rend dans `/DATA/docker/dockerfiles`.
-
-Il faut être connecté au registre de test pour la suite : on s'assure de bien avoir exécuté la commande `docker login registry.test.picasoft.net`. Les identifiants sont sur le [pass](https://gitlab.utc.fr/picasoft/interne/pass).
-
-Pour que le service réponde à nos critères, il faut s'assurer qu'il démarre **indépendamment** de ce qui existe sur la machine. Le script [`docker_test.sh`](./docker_test.sh) s'occupe de tout cela pour vous, tout en s'assurant que les URL soient adaptés à la machine de test, par exemple.
-Il suffit de lancer la commande `$ ./docker_test.sh <nom du dossier, e.g. pica-mattermost>`.
-
-Vérifiez que les logs ne produisent aucune erreur et que le service fonctionne bien sur l'infrastructure de test.
-
-En cas d'erreur, vous pouvez lancer des commandes manuellement, relancer le service, changer les fichiers de configurations, etc, pour diagnostiquer.
-
-Lorsque le test a fonctionné, on se rend sur la page [Pipelines](https://gitlab.utc.fr/picasoft/projets/dockerfiles/pipelines) on choisit la pipeline correspondant au commit de modification que l'on a testé, et on lance le push de l'image sur le registre de production (`push-prod`).
-
-## Déploiement en production
-
-On se rend sur la machine de production, dans le dossier `/DATA/docker/dockerfiles`.
-
-Si on déploie un service pour la première fois, il faudra copier les fichiers `*.secrets.example` en `*.secrets`, et remplacer les valeurs d'example par des valeurs **secrètes**.
-
-Il faut être connecté au registre de production pour la suite : on s'assure de bien avoir exécuté la commande `docker login registry.picasoft.net`. Les identifiants sont sur le [pass](https://gitlab.utc.fr/picasoft/interne/pass).
-
-Si des volumes sont déclarés `external` (ce que nous ne [recommendons pas](./guide_bonnes_pratiques.md)), il faut les créer manuellement au prélable.
-
-**Certains services présentes des cas particuliers : regardez bien leur README avant de lancer les commandes qui suivent.**
-On peut ensuite se rendre dans le dossier et lancer, en général :
-
-```bash
-# Tirer la nouvelle version des images
-docker-compose pull
-# (Re)création des volumes, des réseaux, des conteneurs
-docker-compose up -d
-# Lecture des logs
-docker-compose logs -f
-```
-
-Attention : un conteneur noté `Unhealthy` à cause d'un mauvais `HEALTHCHECK` sera **exclu** de Traefik, même s'il fonctionne bien!
-
-## Exemple de test et de déploiement complet
-
-Je me rends sur `pica01-test` et je teste la nouvelle version de l'image :
-
-```bash
-$ ssh qduchemi@pica01-test.picasoft.net
-qduchemi@pica01-test:~$ cd /DATA/docker/dockerfiles
-qduchemi@pica01-test:/DATA/docker/dockerfiles$ ./docker_test.sh pica-mattermost
-Starting procedure for pica-mattermost/...
-
-==== Create dumb secret files ====
-	File pica-mattermost//secrets/mattermost-db.secrets created
-
-==== Stop and remove existing containers ====
-Network docker_default is external, skipping
-
-==== RESET HARD and pull Dockerfiles repository ====
-Using branch  master, is this correct ? [y/N]
-y
-HEAD is now at 472e0d7 [Mattermost] Bump to version 5.19.0
-Username for 'https://gitlab.utc.fr': qduchemi
-Password for 'https://qduchemi@gitlab.utc.fr':
-Already up-to-date.
-
-==== Replace production URL with testing URL in all files ====
-	Found in ./entrypoint.sh
-	Found in ./docker-compose.yml
-
-==== Remove and re-create named external volumes ====
-mattermost-config
-mattermost-config
-mattermost-data
-mattermost-data
-mattermost-plugins
-mattermost-plugins
-mattermost-db
-mattermost-db
-
-==== Remove old images ====
-Error: No such image: registry.test.picasoft.net/pica-mattermost:5.19.0
-Error: No such image: postgres:9.4-alpine
-
-==== Pull new versions of images ====
-Pulling mattermost-db ... done
-Pulling mattermost    ... done
-
-==== Lauch pica-mattermost ====
-Creating mattermost-db ... done
-Creating mattermost-app ... done
-
-==== Print logs (use Ctrl+C to stop) ====
-Attaching to mattermost-app, mattermost-db
-[...]
-```
-
-Je vérifie que les logs sont ok, je se rend sur [team.test.picasoft.net](https://team.test.picasoft.net) et je constate que tout fonctionne.
-
-Je me rends de nouveau sur le [pipeline](https://gitlab.utc.fr/picasoft/projets/dockerfiles/pipelines/54707) et je lance manuellement l'étape `push-prod` pour pousser l'image sur le registre de production.
-
-Je me rends ensuite sur la machine de production (`pica02` à ce jour) et je lance la nouvelle version du service :
-```bash
-$ ssh qduchemi@pica02.picasoft.net
-qduchemi@pica02:~$ cd /DATA/docker/dockerfiles/pica-etherpad
-qduchemi@pica02:/DATA/docker/dockerfiles$ docker-compose pull
-Pulling mattermost-db ... done
-Pulling mattermost    ... done
-qduchemi@pica02:/DATA/docker/dockerfiles$ docker-compose up -d
-Recreating mattermost-db ... done
-Recreating mattermost-app ... done
-qduchemi@pica02:/DATA/docker/dockerfiles$ docker-compose logs -f
-Attaching to mattermost-app, mattermost-db
-[...]
-```
-
-J'attends que l'application ait démarré, je vérifie que tout est ok sur [team.picasoft.net](https://team.picasoft.net).
-
-La mise à jour est terminée ! :)
-
-## Troubleshooting
-
-Cette section répertorie les problèmes anecdotiques indépendants des modifications des fichiers.
-
-### Erreurs de connexion à la base de données
-
-Si le conteneur `*-app` n'arrive pas à se connecter à la BDD du conteneur `*-db`, il est possible que `*-db` soit en train de tourner avec des anciens identifiants. Pour corriger ce problème **sur la VM de test**, il faudra:
-
-* effacer les conteneurs `*-app` et `*-db`
-* effacer leurs volumes
-* créer à nouveau leurs volumes
-* relancer le script `./docker_test.sh`.
-
-**Note:** Le script s'occupe déjà d'effacer et créer à nouveau les volumes, mais ça ne fonctionne pas dans le cas de `pica-etherpad`, probablement dû à un bug de `docker-compose config --volumes` qui retourne `etherpad-db-volume` et non `etherpad-db`.
diff --git a/doc/guide_developpeur_ci.md b/doc/guide_developpeur_ci.md
deleted file mode 100644
index 2e4102a4166bbfc52ff148760b80d4b56e7743d3..0000000000000000000000000000000000000000
--- a/doc/guide_developpeur_ci.md
+++ /dev/null
@@ -1,48 +0,0 @@
-# Explications et améliorations de la CI
-
-Cette section répertorie des détails un peu plus poussés sur le fonctionnement de la chaîne d'intégration, qui viendraient parasiter le guide de fonctionnement normal.
-
-Tout est configuré dans le fichier [.gitlab-ci.yml](../.gitlab-ci.yml). Sa lecture est sans doute un peu cryptique pour certaines parties, on pourra consulter la documentation de Gitlab pour l'explication des différentes directives.
-
-## Formalisme du dépôt
-
-Pour que la CI fonctionne correctement, il faut respecter plusieurs contraintes. Il ne s'agit pas de bonnes pratiques, mais de conventions (discutables).
-
-On peut utiliser le [template fourni](../template) pour partir sur une bonne base.
-
-* Chaque service géré par la chaîne d'intégration a son dossier `pica-*` ou `meta-*`,
-* Chaque dossier contient au moins un `Dockerfile`, un `docker-compose.yml` et un `clair-whitelist.yml`,
-* Le nom final de l'image est spécifiée dans le `docker-compose.yml`, au format `registry.picasoft.net/nom:version`, et le nom doit correspondre au dossier,
-* Les secrets sont répertoriés dans des fichiers `*.secrets.example` dans un sous-dossier `secrets`, avec des valeurs d'exemple,
-* Les fichiers de secrets sont injectés dans le conteneur via la directive `env_file`, sans l'extension `.example`.
-
-Sur la machine où est clonée le dépôt :
-* Le dossier `secrets` doit avoir comme permissions `770` et les fichiers à l'intérieur de ce dossier `660`. Tous les dossiers et fichiers de ce dépôt doivent avoir pour groupe `docker` (gid: `999`),
-
-## Des analyses de sécurité ?
-
-Les analyses de sécurité permettent d'auditer les images Docker que nous construisons, afin de prévenir un maximum de failles de sécurité sur nos services. En effet, bien que les conteneurs Docker soient en théorie isolés du système lui-même, ils contiennent des données critiques. Il faut donc s'assurer que l'image est suffisamment propre avant de la lancer, d'autant qu'on se base parfois sur des images pré-construites.
-
-Les analyses sont de deux types : statique ou dynamique.
-
-L'analyse statique est effectuée par [Clair Scanner](https://github.com/arminc/clair-scanner) : son objectif est d'analyser l'intégralité des paquets installés dans une image Docker et de reporter les vulnérabilités présentes sur ces paquets ([CVE, ou Common Vulnerabilities and Exposures](https://cve.mitre.org/)). Cette analyse ne dit rien sur la sécurité du **service** en lui-même, mais plutôt sur la sécurité des bibliothèques dont il dépend.
-
-Cette analyse n'échoue que lorsque des CVE de niveau `High` ou plus sont détectées. Le fichier `clair-whitelist.yml` sert justement à autoriser certaines CVE de niveau `High` à contourner cette restriction, après une analyse qui aurait déterminé qu'elle n'affecte pas la sécurité de notre service.
-
-L'analyse dynamique est effectuée par [Docker Bench for Security](https://github.com/docker/docker-bench-security), qui lance le service en interne et vérifie que le ou les conteneurs lancés respectent une liste de bonnes pratiques. Docker Bench for Security ne fait jamais échouer la CI, même lorsque les bonnes pratiques ne sont pas respectées, car ce n'est pas toujours possible. Il faut néanmoins tendre vers le respect de ces bonnes pratiques. En pratique, nous utilisons très peu cette étape et sa pertinence devra être discutée.
-
-## Étapes manuelles ou automatiques ?
-
-Le push sur le registre de production est **toujours** manuel, car il faut s'assurer au préalable que le service a été testé par un humain avant de le pousser.
-
-La mise à jour d'un `Dockerfile` entraîne le lancement de l'ensemble de la CI.
-
-La mise à jour d'une liste blanche de CVE (voir [Formalisme du dépôt](#formalisme-du-dpt)) déclenche uniquement l'analyse de sécurité statique sur la dernière image construite (pas de nécessité de reconstruire l'image).
-
-La mise à jour d'un `docker-compose.yml` déclenchait l'analyse de sécurité dynamique sur la dernière image construite (pas de nécessité de reconstruire l'image) : à présent, elle n'est déclenchée que manuellement.
-
-La mise à jour d'un fichier autre donne la possibilité de déclencher manuellement les étapes de la CI : on appréciera au cas par cas s'il est nécessaire de reconstruire l'image. Par exemple, mettre à jour le `README` ou un fichier de secrets d'exemple ne devrait pas déclencher la CI, tandis que mettre à jour un fichier de configuration devrait déclencher la CI.
-
-## Meta-images
-
-On prévoit à terme d'utiliser ce dépôt pour construire aussi les images qu'il utilise lui même. Pour l'instant, c'est en test avec `meta-registry-test` pour construire l'image utilisée par le registry docker sur `pica01-test`.
diff --git a/doc/guide_utilisateur_ci.md b/doc/guide_utilisateur_ci.md
deleted file mode 100644
index ff22784cd4b2773e3c695b1b9d3d8120ae133d37..0000000000000000000000000000000000000000
--- a/doc/guide_utilisateur_ci.md
+++ /dev/null
@@ -1,85 +0,0 @@
-# Utilisation de la chaîne d'intégration
-
-## Introduction
-
-Ce dépôt utilise la [chaîne d'intégration de Gitlab](https://docs.gitlab.com/ee/ci/), ou **CI**, pour automatiser certaines tâches dès lors que des changements ont lieu sur le dépôt. L'idée est en particulier d'automatiser la construction des images Docker et les analyses de sécurité, ce qui permet d'améliorer la sécurité de l'infrastructure, d'unifier les procédures, de garder un historique clair des modifications et de synchroniser l'état des services sur les machines avec l'état de ce dépôt.
-
-La CI est déclenchée dès lors qu'une modification est susceptible d'altérer un service est détectée.
-
-Elle va effectuer les opérations suivantes, partiellement ou complètement selon le contexte :
-* Construction de l'image Docker et push vers le registre de test,
-* Analyses de sécurité,
-* Push vers le registre de production.
-
-Chaque étape peut échouer et bloquer les étapes ultérieures. Il faudra régler les problèmes et mettre à jour le dépôt afin de relancer la CI le cas échéant.
-
-## Mettre à jour un service
-
-On peut vouloir mettre à jour :
-* Le service (*e.g.* changer un numéro de version dans le Dockerfile),
-* La configuration (éditer un fichier quelconque),
-* La configuration des volumes (*e.g.* changer le point de montage du Docker Compose),
-* etc.
-
-En principe, il suffit de récupérer ce dépôt, de faire les mises à jour souhaitées, de commit les changements et de les pousser pour que l'image soit construite si besoin. Le cas échéant, pour des services "maisons", il est de bon ton de mettre à jour un fichier `CHANGELOG.md` pour résumer les modifications.
-
-Si le code du service à mettre à jour est intégré au dépôt par un submodule, on lancera la commande suivante pour le mettre à jour à la dernière version. Voir la documentation des submodules pour utiliser un tag ou une branche spécifique.
-```
-git submodule update --recursive --remote <dossier du service>
-```
-
-Si vous mettez à jour un fichier de configuration qui nécessite de reconstruire l'image, il faudra lancer la CI manuellement depuis la page [Pipelines](https://gitlab.utc.fr/picasoft/projets/dockerfiles/pipelines). Si vous mettez à jour un fichier de configuration qui est monté dans le conteneur via Docker Compose, aucune action de la CI n'est nécessaire, **même pas l'action `push-prod`**.
-
-Notez que le **nom final** de l'image construite est celui que vous indiquez dans le `docker-compose.yml`. Si vous mettez à jour un service en lui-même (option 1 de la liste ci-dessus), il faut impérativement modifier la version de l'image construite dans ce fichier dans le `docker-compose.yml`.
-
-**Attention, la CI se déclenche en regardant les modifications apportées lors du dernier commit. Si vous modifiez le `Dockerfile` dans un commit, puis le `README` dans un autre, et que vous poussez le tout, la construction ne se déclenchera pas automatiquement.**
-
-Vous pouvez suivre les différentes étapes de la CI sur la page [Pipelines](https://gitlab.utc.fr/picasoft/projets/dockerfiles/pipelines), et il est **recommandé** de lire les logs des différentes étapes en cliquant sur chacune d'entre elles. Si la construction et les analyses de sécurité se passent bien, tous les voyants sont au vert (sauf la dernière étape, qui doit être déclenchée manuellement). Sinon, référez-vous à la section [Troubleshooting](#troubleshooting). Si l'analyse de sécurité n'est pas déclenchée, c'est qu'elle n'a pas besoin de l'être.
-
-Enfin, il est de bon ton de vérifier que les CVE whitelistées dans le fichier `clair-whitelist.yml` sont toujours détectées dans le scan de Clair (étape `clair`). Si non, on pourra les enlever de la liste.
-Notez aussi que souvent, les nouvelles CVE sont classées `High`, puis rétrogradée en `Medium`, voire `Negligeable`, parce qu'on s'est rendu compte que l'impact est moins grand qu'on le croyait. Dans ce cas, il convient d'enlever les CVE retrogradées de la liste blanche.
-
-On peut ensuite [déployer le service](guide_deploiement.md).
-
-## Exemple de mise à jour
-
-On veut mettre à jour Mattermost de la version 5.18.0 à la version 5.19.0. On fait les modifications dans le Dockerfile et on pousse le commit. Les modifications dépendent évidemment du service, on peut voir le commit [472e0d72](https://gitlab.utc.fr/picasoft/projets/dockerfiles/commit/472e0d72534659e215270adade6746b65b6f65e3) pour l'exemple.
-
-Le [pipeline](https://gitlab.utc.fr/picasoft/projets/dockerfiles/pipelines/54707) se lance automatiquement. Je suis les logs des jobs un par un pour vérifier que tout se passe bien.
-
-La construction de l'image et les analyses de vulnérabilité se passent bien : aucun paquet n'introduit de nouvelle vulnérabilité.
-
-Je [déploie la nouvelle version du service](./guide_deploiement.md).
-
-Si tout se passe bien, je me rends de nouveau sur le [pipeline](https://gitlab.utc.fr/picasoft/projets/dockerfiles/pipelines/54707) et je lance manuellement l'étape `push-prod` pour pousser l'image sur le registre de production.
-
-## Astuces
-
-Il est possible de relancer une pipeline plus ancienne, pour reconstruire une ancienne version de l'image, quand cela est nécessaire, et revenir exactement dans l'état du commit concerné.
-
-## Troubleshooting
-
-Des erreurs peuvent survenir à plusieurs étapes de la CI.
-Les logs de chaque étape donnent des informations sur la nature de l'erreur.
-
-### Impossibilité de pull une image
-
-Parfois, un timeout empêche de pull l'image depuis le registre de test entre deux étapes, avec des messages de timeout ou de type `Unknown blob`. Il faudra dans ce cas redémarrer le registre de test (sur `pica01-test`, probablement) et relancer la chaîne d'intégration.
-
-### Lors de la construction de l'image
-
-Si l'erreur ne vient pas d'un Dockerfile mal écrit, elle peut venir d'un nom d'image mal formaté dans le Docker Compose (voir [Formalisme du dépôt](./guide_developpeur_ci#formalisme-du-dpt)).
-
-### Lors de l'analyse de sécurité statique
-
-Cette analyse échoue lorsque des CVE avec une criticité `High` ou plus sont détectées. Les CVE de niveau plus faible étant inévitables, la CI n'échoue pas et se contente de les afficher.
-
-Clair vous indique quels paquets sont vulnérables. Plusieurs choix s'offrent à vous : mitiger la CVE (choix à privilégier) ou mettre la CVE en liste blanche.
-
-On regardera à ce titre le [Mini guide pour mitiger une CVE !](mini_guide_cve.md)
-
-Ensuite, on pousse les modifications et la CI ré-effectuera les tests de vulnérabilités, en reconstruisant l'image si nécessaire.
-
-### Lors de l'analyse de sécurité dynamique
-
-Il est fort probable que l'erreur provienne d'un mauvais Docker Compose, et que Docker Bench for Security n'arrive pas à lancer votre ou vos conteneur(s), par exemple à cause d'un fichier manquant ou d'un mauvais formattage.
diff --git a/doc/images/clair_log_1.png b/doc/images/clair_log_1.png
deleted file mode 100644
index 122ba761aeff7f593dfd1abe230817eea2170801..0000000000000000000000000000000000000000
Binary files a/doc/images/clair_log_1.png and /dev/null differ
diff --git a/doc/images/clair_log_2.png b/doc/images/clair_log_2.png
deleted file mode 100644
index 9cd2ca831173472dbcdb8771ddc18b65a7e6b0df..0000000000000000000000000000000000000000
Binary files a/doc/images/clair_log_2.png and /dev/null differ
diff --git a/doc/launch_service.md b/doc/launch_service.md
new file mode 100644
index 0000000000000000000000000000000000000000..8bca9b78fbc1d889a20ddeec129e48fb3b8f594a
--- /dev/null
+++ b/doc/launch_service.md
@@ -0,0 +1,89 @@
+## Administration des services
+
+Chaque service versionné sur ce dépôt est lancé sur une des machines virtuelles de Picasoft.
+
+En particulier, les fichier `docker-compose.yml` présents dans chaque dossier, ainsi que les fichiers de configuration et de secrets, permettent de lancer n'importe quel service de façon autonome, sur n'importe quel machine.
+
+Pour chacune des opérations détaillées dans cette page, on suppose que :
+* Vous savez sur quel machine tourne ou doit tourner le service (`pica01`, `monitoring`...)
+* Vous avez une connexion SSH active sur cette machine
+* Vous êtes dans le dossier `<clone_depot>/<service>`, sur la branche `master`. Le clone devrait se trouver dans `/DATA/docker/dockerfiles`.
+* Vous êtes connecté au registre de production : on s'assure de bien avoir exécuté la commande `docker login registry.picasoft.net`. Les identifiants sont sur le [pass](https://gitlab.utc.fr/picasoft/interne/pass).
+
+La branche `master` devant refléter l'état des services en production, toutes les opérations sur les machines de production devront être réalisées depuis `master` : cela signifie que les branches sur lesquelles vous travaillez devront être fusionnées à la fin de vos tests, et donc avant la mise en production.
+
+### Opérations usuelles
+
+Consulter les logs d'un service à la recherche d'une erreur :
+
+```bash
+# n est le nombre de lignes à afficher, optionnel
+docker-compose logs -f [--tail <n>]
+```
+
+Redémarrer un service, par exemple si celui-ci a planté :
+
+```bash
+# Le nom du service est optionnel : si on veut tout
+# redémarrer, on ne le met pas. Sinon, on indique
+# le nom du service présent dans le fichier
+# docker-compose.yml.
+docker-compose restart [service]
+```
+
+Re-créer le conteneur si nécessaire, par exemple suite à une mise à jour de l'image ou de la configuration :
+
+```bash
+docker-compose pull
+# Le nom du service est optionnel : si on veut tout
+# redémarrer, on ne le met pas. Sinon, on indique
+# le nom du service présent dans le fichier
+# docker-compose.yml.
+docker-compose up -d [service]
+```
+
+Le `docker-compose pull` est **essentiel** : il permet de récupérer les nouvelles versions des images et de s'assurer qu'on a bien la dernière version indiquée dans le Compose.
+
+Éteindre un service :
+```bash
+docker-compose stop
+```
+
+etc.
+
+Attention : un conteneur noté `Unhealthy` à cause d'un mauvais `HEALTHCHECK` sera **exclu** de Traefik, même s'il fonctionne bien!
+
+### Lancement d'un nouveau service
+
+Lorsque vous lancez un nouveau service, il y a parfois quelques opérations à faire avant de lancer les conteneurs.
+En effet, bien qu'en théorie un `docker-compose up -d` suffise, il y a quelques cas particulier.
+
+#### Secrets
+
+Les secrets, tels que les mots de passe, ne sont évidemment pas présents sur ce dépôt. Lorsque des secrets sont utilisés, ils sont **systématiquement** indiqués par la présence de fichiers dans un sous-répertoire `secrets`.
+
+Dans ce cas, on copiera tous les fichiers `.secrets.example` en `.secrets`, et on remplacera les valeurs.
+
+Cette opération n'est nécessaire que lors du premier lancement.
+Il y a plusieurs situations.
+
+1. Le mot de passe est "inédit", et ne concerne pas les utilisateurs (comme le mot de passe d'un utilisateur de base de données). On pourra générer un mot de passe avec la commande suivante :
+
+```bash
+< /dev/urandom tr -dc _A-Z-a-z-0-9 | head -c${1:-32};echo;
+```
+
+2. Le mot de passe est connu, par exemple le mot de passe d'un compte LDAP. On le récupérera sur le [pass](https://gitlab.utc.fr/picasoft/interne/pass).
+3. Le mot de passe est "inédit", mais doit être accessibles aux administrateurs (par exemple le mot de passe d'administration d'Etherpad). On le créera directement dans le [pass](https://gitlab.utc.fr/picasoft/interne/pass) (`picapass insert...`) et on le copiera dans le fichier de secrets.
+
+#### Création des volumes
+
+Si des volumes sont déclarés `external` dans le fichier Compose (ce que nous ne [recommendons pas](./guide_bonnes_pratiques.md)), il faut les créer manuellement au prélable :
+
+```bash
+docker volume create <volume>
+```
+
+#### Opérations manuelles
+
+Certains services (comme [le serveur mail](../pica-mail)) nécessitent des opérations manuelles : créer des dossiers, puis générer des clés ou des certificats... Il faudra être attentif à le faire avant tout lancement.
diff --git a/doc/new_service.md b/doc/new_service.md
new file mode 100644
index 0000000000000000000000000000000000000000..d66d5d47a4e2a63b4e1a182cba733f7a6c4c0c3e
--- /dev/null
+++ b/doc/new_service.md
@@ -0,0 +1,61 @@
+# Versionnage d'un nouveau service
+
+L'idée de ce dépôt est de rendre nos services **indépendants** des machines virtuelles sur lesquels ils sont lancés, c'est-à-dire qu'à partir de ce dépôt, on devrait pouvoir remonter sans aucun problème un service sur une machine quelconque (sauf les données, bien sûr).
+
+Cette page donne quelques pistes pour versionner un nouveau service sur ce dépôt.
+
+On pourra partir du dossier [template](../template) comme base.
+
+Pour le contenu des fichiers `Dockerfile` et `docker-compose.yml`, on se réferera au [guide des bonnes pratiques](./guide_bonnes_pratiques.md) en cas de doute.
+
+## Choix des fichiers à versionner
+
+Pour savoir si vous avez versionné tout les fichiers nécessaires, posez-vous la question suivante :
+
+> Si je fais un `git pull` puis un `docker-compose up -d`, est-ce-que mon service démarre correctement ?
+
+Si oui, vous avez versionné les fichiers nécessaires. Si non, il faut remédier au problème. La seule exception concerne les opérations nécessaires pour créer les secrets (voir plus bas).
+
+### Fichiers nécessaires
+
+Pour chaque service, on aura au moins :
+* Un `README.md`, qui explique de quoi il s'agit, comment lancer le service, comment le mettre à jour, etc. On pourra s'inspirer des services existants et du template.
+* Un `docker-compose.yml`, qui permet de lancer le service sur les machines de Picasoft. Les images utilisées doivent toujours avoir un tag de version précis (voir bonnes pratiques).
+
+### Image personnalisée
+
+Si on utilise une image construite par nos soins, il faut rajouter :
+* Un ou plusieurs `Dockerfile`, qui permet(tent) de construire l'image.
+* Un `CHANGELOG.md`, qui indique les modifications effectuées au fil des versions.
+
+Le Dockerfile peut contenir des directives `COPY` pour ajouter des fichiers à l'image. S'il s'agit d'un ou deux fichiers de configuration, ou d'un entrypoint, aucun souci pour le versionner sur ce dépôt. S'il s'agit de code à proprement parler, il est préférable de créer un dépôt spécifique qui contiendra le code du service, et de faire un `git pull` dans le `Dockerfile` (ou d'utiliser un sous-module Git).
+
+En effet, ce dépôt n'est pas voué à contenir le code des services, mais simplement les fichiers nécessaires pour construire l'image, configurer et lancer le service.
+
+### Fichiers de configuration
+
+Il est préférable de versionner la configuration du service sur ce dépôt, pour pouvoir relancer rapidement le service sur une machine quelconque sans devoir récupérer la configuration sur l'ancienne machine.
+
+Cependant, si la configuration est souvent modifiée via l'interface d'administration du service, il est préférable de ne pas la versionner. Par exemple, Mattermost utilise un fichier `config.json`, mais on le modifie essentiellement à travers la Console Administrateur (interface graphique). Versionner ce fichier obligerait à modifier la configuration "à la main", puis à redémarrer Mattermost à chaque changement de paramètre.
+
+Par contre, Etherpad utilise un fichier `config.json` qui n'est pas modifiable via une interface graphique, et qui est pris en compte uniquement au démarrage. C'est donc un bon fichier à versionner.
+
+La *rule of thumb* est donc la suivante : on versionnera **tous les fichiers qui ne sont pas modifiés dynamiquement quand le service est lancé**.
+
+### Cas particuliers
+
+Certaines images officielles demandent d'effectuer des opérations manuellement avant de les lancer (initialisation de base de données, etc).
+
+Dans ce cas, on pourra créer un `entrypoint` qui remplace l'officiel et qui effectue ces opérations si jamais le service est lancé pour la première fois, puis qui lance le service normalement. On pourra marquer le fait qu'un service a déjà été initialisé en créant un fichier "marqueur" dans un volume. Voir [Plume](../pica-plume) pour un exemple.
+
+De manière générale, on hésitera pas à faire un `entrypoint` personnalisé si celui de l'image officielle ne suffit pas à nos besoins et qu'on ne peut pas configurer le service comme on le veut grâce aux variables d'environnement.
+
+## Gestion des secrets
+
+Un service a souvent besoin de secrets pour démarrer. Par secrets, on entend souvent mot de passe, ou clé privée.
+
+En général, les secrets sont configurés via des variables d'environnement. Quand c'est le cas, on créera un dossier `secrets`, puis des fichiers en `.secrets.example` qui contiennent une variable d'environnement par ligne. Voir les services existants pour un exemple.
+
+Quand le service demande les secrets en clair dans un fichier de configuration, et qu'on ne peut pas faire référence aux variables d'environnement dans le fichier, on gardera le système des variables d'environnement et on remplacera l'`entrypoint` pour injecter les variables dans le fichier de configuration.
+
+On trouvera un exemple dans [pica-metrics-bot](../pica-metrics-bot), où l'on voit que le fichier de configuration contient des marqueurs (`INFLUXDB_USER` par exemple), qui sont remplacés au démarrage du service par les valeurs des variables d'environnement correspondantes.
diff --git a/doc/update_and_test.md b/doc/update_and_test.md
new file mode 100644
index 0000000000000000000000000000000000000000..09caf7459677fe21efae571fa6a2de277503d1ca
--- /dev/null
+++ b/doc/update_and_test.md
@@ -0,0 +1,180 @@
+# Mise à jour et test d'un service
+
+Cette page indique les différentes manières de mettre à jour un service et de le tester, avant sa mise en production.
+
+On peut vouloir mettre à jour :
+* Le service (*e.g.* changer un numéro de version dans le Dockerfile),
+* La configuration (éditer un fichier quelconque),
+* La configuration des volumes (*e.g.* changer le point de montage du Docker Compose),
+* etc.
+
+Dans tous les cas, les modifications apportées à n'importe quel fichier de ce dépôt **doivent être poussées sur ce dépôt**.
+Vous pouvez effectuer les modifications sur votre machine ou sur une machine de Picasoft, du moment qu'elles sont synchronisées avec le dépôt.
+
+## Comment mettre à jour un service ?
+
+Il est pertinent de créer une branche avant chaque mise à jour où vous n'êtes pas sûr des modifications, et ne de fusionner dans `master` que lorsque les tests ont été effectués.
+
+### Mise à jour de la configuration
+
+On appelle configuration tout ce qui ne nécessite pas de reconstruire une image :
+* Modification du `docker-compose.yml` (environnement, point de montage, tag d'une image officielle...)
+* Modification d'un fichier de configuration
+* Modification d'une page web d'accueil
+* etc.
+
+Il suffit de mettre à jour les fichiers souhaitées, éventuellement de signaler les changements à l'équipe ou en commentaire, puis de synchroniser avec le dépôt.
+
+Si vous mettez à jour le tag d'une image officielle (*e.g* `postgres:10` → `postgres:12`), lisez au préalable la documentation de mise à jour ! Certaines nécessitent des interventions manuelles, et le README du service le précise en général.
+
+Toute image indiquée dans le fichier Compose **doit avoir un tag** (*e.g* `postgres:12` et pas `postgres`). N'utilisez jamais un tag vide (équivalent à `latest`).
+
+### Mise à jour d'une image maison
+
+Apportez vos modifications au Dockerfile (ajout d'un paquet...). Vous pouvez travailler en local et tester l'image sur votre machine si vous voulez.
+
+Si le code du service à copier dans l'image est intégré au dépôt par un submodule, on lancera la commande suivante pour le mettre à jour à la dernière version. Voir la documentation des submodules pour utiliser un tag ou une branche spécifique.
+```
+git submodule update --recursive --remote <dossier du service>
+```
+
+Synchronisez ensuite le tout avec le dépôt (`git commit`, `git push...`).
+
+## Comment tester le service mis à jour ?
+
+Avant de mettre en production un service, il faut s'assurer que la mise à jour n'a rien cassé. Même si vous avez testé la nouvelle image sur votre machine, il faut également la tester sur l'infrastructure de Picasoft, en particulier parce que les services ont souvent besoin de Traefik pour fonctionner.
+
+Pour ce faire, rendez-vous sur `pica01-test`, dans le clone du dépôt (usuellement `/DATA/docker/dockerfiles`).
+
+Attention, notez que parfois il y a des problèmes indépendants du service quand celui-ci est accessible via Traefik :
+* Tant que le `HEALTHCHECK` n'est pas passé, Traefik ne route pas vers le service (on vérifiera que le conteneur est noté `healthy` dans la sortie de `docker ps`)
+* Parfois, Traefik ne route pas vers le service et renvoie un `Gateway Timeout`. Un `docker restart traefik` résoud le problème s'il vient de là.
+
+### Automatiquement
+
+Le script [docker_test.sh](../docker_test.sh) permet d'automatiser toutes les étapes pour tester un service et s'assurer qu'il fonctionne bien indépendamment des données précédentes, qui auraient été conservées dans un volume, par exemple. Il permet aussi de remplacer toutes les URL de production par des URL de test.
+
+Il a le désavantage qu'on comprend moins ce que l'on fait. Pour s'en servir, lancez :
+
+```bash
+$ ./docker_test.sh <nom du dossier, e.g. pica-mattermost>
+```
+
+Vérifiez que les logs ne produisent aucune erreur et que le service fonctionne bien sur l'infrastructure de test, en y accédant via son URL par exemple (attention : remplacer `picasoft.net` par `test.picasoft.net` dans votre navigateur).
+
+### Manuellement
+
+Si vous voulez tester le service "à la main", ou que le script ne fonctionne pas pour vous, ou pour toute autre raison, suivez ces étapes :
+
+#### Synchronisation
+
+Synchronisez vous **exactement** avec le dépôt :
+
+```bash
+# master ou votre branche perso
+git checkout <votre branche>
+git pull
+```
+
+#### Remise à zéro
+
+Si le service était déjà lancé sur la machine de test, éteignez-le et remettez les volumes à 0 :
+
+```bash
+docker-compose down -v
+```
+
+Si des volumes sont déclarés comme `external` dans le fichier Compose, supprimez-les manuellement :
+
+```bash
+docker volume rm <volume>
+```
+
+#### Construction des images
+
+Si le service utilise des images "maison", il faut les construire. Si le fichier Compose est bien fait, il suffit de lancer :
+
+```bash
+docker-compose build
+```
+
+Sinon, il faut construire les images à la main. À répéter pour chaque image maison du service concerné :
+
+```bash
+docker build [-f <Dockerfile>] -t <image> <context>
+```
+
+* Si le `Dockerfile` a un nom différent, on utilise le switch `-f`
+* `<image>` doit avoir rigoureusement la valeur de la directive `image` du fichier Compose
+* `<context>` est le contexte que reçoit Docker pour construire l'image (base pour copier les fichiers). En général, c'est le dossier du service (donc `.`, puisqu'on est dedans).
+
+#### Remplacement des URLs
+
+Si nécessaire. Certains services ne sont pas accessibles depuis Internet.
+
+Remplacez les URL de production (`.picasoft.net`) par des URL de tests (`.test.picasoft.net`), sauf dans le nom de l'image :
+
+* Si le service utilise Traefik, voir du côté de `traefik.frontend.rule` dans le fichier Compose
+* Si le service utilise des fichiers de configuration, remplacez les références aux URL...
+
+### Créer les fichiers d'example
+
+Copier tous les `.secrets.example` en `.secrets`.
+
+#### Récupérer les nouvelles images
+
+Si le service utilise des images officielles, on s'assure qu'elles sont bien à jour avec la commande :
+
+```bash
+docker-compose pull
+```
+
+#### Lancer le service
+
+```bash
+docker-compose up -d
+```
+
+#### Vérifier que tout fonctionne bien
+
+```bash
+docker-compose logs -f
+```
+
+On constate l'absence d'erreurs dans les logs, et si le service est accessible via Internet, on regarde que tout fonctionne bien depuis l'URL de test.
+
+### En cas de problème
+
+À partir de là, c'est carte blanche : on peut modifier la configuration, le Dockerfile, reconstruire les images, etc. L'infrastructure de test est un bac à sable.
+
+Si jamais les modifications ont permis de résoudre le problème, on les commit et on les synchronise avec le dépôt.
+
+### Revenir à l'état initial
+
+On se resynchronise avec l'état du dépôt en enlevant toutes les modifications induites par les tests.
+```bash
+git reset --hard
+```
+
+## Que faire après les tests ?
+
+Une fois qu'on est convaincu que la nouvelle version du service fonctionne bien, on peut le mettre en production.
+
+Au préalable, si le service utilise des images maison, on les pousse sur le registre de production. Pour ce faire, vous devez connecté au registre de production : on s'assure de bien avoir exécuté la commande `docker login registry.picasoft.net`. Les identifiants sont sur le [pass](https://gitlab.utc.fr/picasoft/interne/pass).
+
+```bash
+docker-compose push
+```
+
+Cette commande pratique indique à Docker Compose de pousser toutes les images du fichier.
+
+On peut aussi le faire manuellement, pour chaque image maison (*i.e.* dont le nom commence par `registry.picasoft.net`) :
+
+```bash
+# <image> doit correspondre exactement
+# à la directive image du fichier Compose
+# et commencer par registry.picasoft.net
+docker push <image>
+```
+
+Une fois les images poussées, on se rend sur la machine de production et on [lance le service](./launch_service.md).