L'objectif, c'est la reproductibilité et l'explicitation des
dépendances. L'intégration continue est un moyen d'y arriver mais je
dirais que notre objectif n'est pas d'en faire des experts de
développement logiciel et de l'intégration continue.
Ayant peu d'expérience avec Docker, je me suis appuyé sur la
[[https://people.irisa.fr/Anthony.Baire/docker-tutorial.pdf][présentation d'Anthony Baire]] pour préparer cette séquence.
* Objectifs et Problématique
* Objectifs et Problématique
** Problématiques:
L'objectif de cette séquence est de vous familiariser avec les notions
- Alice a son propre environnemnet, Bob a le sien. Le code/notebook
d'*environnement logiciel*, l'importance du contrôle de cet
qu'Alice exécute ne s'exécute pas sur la machine de Bob et
environnement, et de vous présenter les outils vous permettant d'y
arriver. En particulier, nous verrons comment utiliser des *conteneurs*,
comment utiliser un système de *gestions de paquets* pour construire un
environnement donné, et même l'outil d'*intégration continue* de gitlab
pour automatiser un test dans un environnement logiciel spécifique.
Notre objectif n'est pas de faire de vous des experts de chacun de ces
outils mais de vous familiariser avec chacun d'eux et que vous
compreniez leur périmètre afin que vous sachiez contrôler et
expliciter vos dépendances logicielles.
** Problématique
- Alice a son propre environnement, Bob a le sien. Le code ou le
notebook qu'Alice exécute ne s'exécute pas sur la machine de Bob et
réciproquement.
réciproquement.
- Bob ne peut pas mettre à jour sa machine (pas les droits, risque
- Bob ne peut pas mettre à jour sa machine (pas les droits, risque
de casser autre chose, pas le même système d'exploitation, etc.)
de casser autre chose, pas le même système d'exploitation, etc.)
- Le code d'Alice s'exécute bien chez Charles mais il ne donne pas
- Étrangement, le code d'Alice s'exécute bien chez Charles mais il ne
le même résultat.
donne pas le même résultat.
- Ce code fonctionnait sur d'anciennes versions mais sur des versions
- Quelques mois plus tard, avant de faire les mises à jour de sa
récentes ce n'est plus le cas.
machine, ce code fonctionnait très bien mais maintenant il ne
fonctionne plus.
** Objectifs
** Objectifs
- Savoir travailler dans un conteneur (*Docker*) pour isoler son travail du reste
À l'issue de cette séquence, vous devriez savoir:
- Travailler dans un conteneur (*Docker*) pour isoler son travail du reste
de sa machine
de sa machine
- Savoir créer un conteneur pour figer un environnement et le partager
- Créer un conteneur pour figer un environnement et le partager
(*Packaging* + *DockerFile*)
(*Packaging* + *DockerFile*)
- Mettre en place un test pour s'assurer de sa robustesse (*Continuous
- Mettre en place un test pour s'assurer de la robustesse d'un code
Integration*) en déportant son exécution dans des environnements
(*Continuous Integration*) en déportant son exécution dans des
controllés
environnements controllés
Nous prendrons comme fil rouge l'exécution d'un notebook jupyter mais
nous montrerons les commandes équivalentes pour Rstudio et Org-Mode
mesure.
* Table des matières et Progression :TOC:
* Table des matières et Progression :TOC:
- [[#objectifs-et-problématique][Objectifs et Problématique]]
- [[#objectifs-et-problématique][Objectifs et Problématique]]
- [[#problématiques][Problématiques:]]
- [[#problématique][Problématique]]
- [[#objectifs][Objectifs]]
- [[#objectifs][Objectifs]]
- [[#séquence-1-familiarisation-avec-le-principe-de-conteneur][Séquence 1: Familiarisation avec le principe de conteneur]]
- [[#séquence-1-familiarisation-avec-le-principe-de-conteneur][Séquence 1: Familiarisation avec le principe de conteneur]]
- [[#11-premiers-pas-avec-docker][1.1 Premiers pas avec Docker]]
- [[#11-premiers-pas-avec-docker][1.1 Premiers pas avec Docker]]
...
@@ -51,31 +63,611 @@ Ayant peu d'expérience avec Docker, je me suis appuyé sur la
...
@@ -51,31 +63,611 @@ Ayant peu d'expérience avec Docker, je me suis appuyé sur la
- [[#25-mettre-son-image-à-disposition][2.5 Mettre son image à disposition]]
- [[#25-mettre-son-image-à-disposition][2.5 Mettre son image à disposition]]
- [[#26-limitations][2.6 Limitations]]
- [[#26-limitations][2.6 Limitations]]
- [[#27-exemple-de-reconstruction-dun-vieil-environnement-optionnel][2.7 Exemple de reconstruction d'un "vieil" environnement (Optionnel)]]
- [[#27-exemple-de-reconstruction-dun-vieil-environnement-optionnel][2.7 Exemple de reconstruction d'un "vieil" environnement (Optionnel)]]
- [[#28-faire-construire-son-image-par-dockerhub-optionnel][2.8 Faire construire son image par dockerhub (Optionnel)]]
- [[#séquence-3-mettre-en-place-un-test-et-utiliser-lintégration-continue-pour-sassurer-de-la-robustesse-dun-code][Séquence 3: Mettre en place un test et utiliser l'intégration continue pour s'assurer de la robustesse d'un code]]
- [[#séquence-3-mettre-en-place-un-test-et-utiliser-lintégration-continue-pour-sassurer-de-la-robustesse-dun-code][Séquence 3: Mettre en place un test et utiliser l'intégration continue pour s'assurer de la robustesse d'un code]]
- [[#31-exécuter-ce-notebook-dans-un-conteneur-et-mettre-en-place-un-test][3.1 Exécuter ce notebook dans un conteneur et mettre en place un test]]
- [[#31-exécuter-ce-notebook-dans-un-conteneur-et-mettre-en-place-un-test][3.1 Exécuter ce notebook dans un conteneur et mettre en place un test]]
- [[#32-activer-lintégration-continue-pour-que-ce-test-soit-exécuté-à-chaque-commit-dans-le-conteneur-de-notre-choix][3.2 Activer l'intégration continue pour que ce test soit exécuté à chaque commit dans le conteneur de notre choix]]
- [[#32-activer-lintégration-continue-pour-que-ce-test-soit-exécuté-à-chaque-commit-dans-le-conteneur-de-notre-choix][3.2 Activer l'intégration continue pour que ce test soit exécuté à chaque commit dans le conteneur de notre choix]]
- [[#33-rajouter-un-test-pour-repérer-si-des-environnements-plus-à-jour-cassent-notre-test][3.3 Rajouter un test pour repérer si des environnements plus à jour cassent notre test]]
- [[#33-rajouter-un-test-pour-repérer-si-des-environnements-plus-à-jour-cassent-notre-test][3.3 Rajouter un test pour repérer si des environnements plus à jour cassent notre test]]
- [[#34-limitations][3.4 Limitations]]
- [[#34-limitations][3.4 Limitations]]
* Séquence 1: Familiarisation avec le principe de conteneur
* TODO Séquence 1: Familiarisation avec le principe de conteneur
#+BEGIN_CENTER
*FIXME*: faire une illustration
#+END_CENTER
Docker va vous permettre d'exécuter des programmes dans ce que l'on
appelle des conteneurs. Un /conteneur/ est une sorte de mini-machine
virtuelle dont le système de fichier est appelé /image/ et qui va
exécuter un /programme/. Je pourrai avoir à un instant donné plusieurs
conteneurs exécutant des programmes différents issus d'images
différentes ou identiques.
- Le premier avantage de cette approche est que votre programme sera
isolé du reste de votre machine et, quoi que vous fassiez dans ce
conteneur, vous n'abimerez pas votre propre machine en installant
des bibliothèques plus anciennes ou plus modernes qui seraient
incompatibles.
- Le second avantage est que vous pourrez préparer plusieurs
conteneurs différents pour vérifier si votre programme fonctionne
toujours bien.
- Enfin, vous pourrez partager ce conteneur avec d'autres de façons à
ce qu'ils puissent exécuter un programme dans les mêmes conditions
que celles que vous aviez prévues.
Si ça vous parait abstrait, le plus simple est de vous montrer comment
ça fonctionne et que vous reveniez sur cette description un peu plus
tard si besoin.
** 1.1 Premiers pas avec Docker
** 1.1 Premiers pas avec Docker
- S'assurer que docker est bien installé
*** TODO S'assurer que docker est bien installé
- Récupérer une image de base
- Exécuter une commande dans un conteneur
#+BEGIN_CENTER
- Utiliser docker en interactif (réaliser qu'il n'y a pas d'effet
*FIXME*: Faire une partie [[https://docs.docker.com/docker-for-windows/][Docker pour Windows]] et Docker pour MacOSX
de bord)
#+END_CENTER
- Partager un répertoire avec un conteneur
Je suis sur une machine linux (une debian) et j'ai donc installé
docker via le paquet =docker.io=. J'ai aussi pris soin de me mettre dans
le groupe docker pour ne pas avoir à passer root à chaque fois. Voici
comment j'ai fait.
#+begin_src shell :results output :exports both :eval never
sudo apt-get install docker.io
sudo adduser alegrand docker
#+end_src
Je peux alors lancer la commande docker et lui demander de quelle
version il s'agit.
#+begin_src shell :session *shell* :results output :exports both
docker version
#+end_src
#+RESULTS:
#+begin_example
Client:
Version: 1.13.1
API version: 1.26
Go version: go1.9.3
Git commit: 092cba3
Built: Thu Feb 1 09:36:44 2018
OS/Arch: linux/amd64
Server:
Version: 1.13.1
API version: 1.26 (minimum version 1.12)
Go version: go1.9.3
Git commit: 092cba3
Built: Thu Feb 1 09:36:44 2018
OS/Arch: linux/amd64
Experimental: false
#+end_example
*** Récupérer une image de base
Nous pouvons commencer. L'idée pour bien contrôler son environnement
va souvent être de partir d'un environnement assez minimaliste et dans
lequel un notebook jupyter n'aura d'ailleurs aucune chance de
s'exécuter. Je partirai d'une image debian stable que je vais
récupérer à l'aide de la commande =docker pull=.
#+begin_src shell :session *shell* :results output :exports both