Découverte de Docker
Configuration
Prérequis
Il n'est pas nécessaire d'avoir des compétences spécifiques pour ce tutoriel, si ce n'est une certaine familiarité avec les command line et l'utilisation d'un éditeur de texte. Une expérience antérieure dans le développement d'applications web sera utile, mais n'est pas nécessaire.
Configuration de votre ordinateur
Comme dit précédemment il vous faudra avoir un outil docker fonctionnel. Pour vérifier que tout focntionne testons une commande docker :
docker run registry.takima.io/school/proxy/hello-world
Unable to find image 'registry.takima.io/school/proxy/hello-world:latest' locally
latest: Pulling from registry.takima.io/school/proxy/hello-world
03f4658f8b78: Pull complete
a3ed95caeb02: Pull complete
Digest: sha256:8be990ef2aeb16dbcb9271ddfe2610fa6658d13f6dfb8bc72074cc1ca36966a7
Status: Downloaded newer image for registry.takima.io/school/proxy/hello-world:latest
Hello from Docker.
...
Ce message indique que votre installation semble fonctionner correctement.
Si ce n'est pas le cas parcourez le Getting Start
pour installer correctement docker
Exécution de votre premier conteneur
Maintenant que vous avez tout configuré, il est temps de mettre les mains dans le cambouis.
Dans cette section, vous allez exécuter un conteneur Alpine Linux (une distribution Linux légère) sur votre système et découvrir la commande docker run
.
Pour commencer, exécutez la commande suivante dans votre terminal pour récuperer (télécharger) l'image depuis le registry takima :
Puis on va tag cette image pour créer une copie et lui donner un nom plus commode à utiliser pour nos prochaines lignes de commandes :
Note
En fonction de la manière dont vous avez installé Docker sur votre système, vous pourriez voir une erreur de permission refusée après avoir exécuté la commande ci-dessus. Essayez les commandes du tutoriel de démarrage pour vérifier votre installation. Si vous êtes sous Linux, vous devrez peut-être préfixer vos commandes docker
avec sudo
. Vous pouvez également créer un groupe Docker pour résoudre ce problème.
La commande pull
récupère l'image Alpine depuis notre registre Docker et la sauvegarde sur notre système. Vous pouvez utiliser la commande docker images
pour voir la liste de toutes les images sur votre système.
Nous aurions pu aussi récupérer une image Docker publique (Docker Hub) qui contient une multitude d'images standard en utilisant :
Cependant Docker Hub est soumis à un rate limit donc nous allons éviter de pull dessus dans cette formation et utiliser le registry Takima.
$ docker images
RÉPERTOIRE TAG ID DE L'IMAGE CRÉÉ TAILLE VIRTUELLE
alpine dernière c51f86c28340 il y a 4 semaines 1,109 Mo
registry.takima.io/school/proxy/alpine dernière c51f86c28340 il y a 4 semaines 1,109 Mo
registry.takima.io/school/proxy/hello-world dernière 690ed74de00f il y a 5 mois 960 o
Exécuter un Docker
Génial ! Exécutons maintenant un conteneur Docker basé sur cette image. Pour cela, nous allons utiliser la commande docker run
.
$ docker run alpine ls -l
total 48
drwxr-xr-x 2 root root 4096 2 mars 16:20 bin
drwxr-xr-x 5 root root 360 18 mars 09:47 dev
drwxr-xr-x 13 root root 4096 18 mars 09:47 etc
drwxr-xr-x 2 root root 4096 2 mars 16:20 home
drwxr-xr-x 5 root root 4096 2 mars 16:20 lib
...
...
Qu'est-il arrivé ? En coulisses, il s'est passé beaucoup de choses. Lorsque vous appelez run
:
-
Le client Docker contacte le daemon Docker.
-
Le daemon Docker vérifie si l'image (dans ce cas, Alpine) est disponible localement, et si ce n'est pas le cas, la télécharge depuis le registry Docker. (Comme nous avons exécuté
docker pull registry.takima.io/school/proxy/alpine
auparavant puis tag cette image en la nommantalpine
, l'étape de téléchargement n'est pas nécessaire) -
Le daemon Docker crée le conteneur, puis exécute une commande dans ce conteneur.
-
Le daemon Docker transmet la sortie de la commande au client Docker.
Lorsque vous exécutez docker run alpine
, vous avez fourni une commande (ls -l
), alors Docker a démarré la commande spécifiée et vous avez vu la liste.
Essayons quelque chose de plus utile : afficher un Hello World bien sur!
OK, voilà une sortie réelle. Dans ce cas, le client Docker a exécuté fidèlement la commande echo
dans notre conteneur Alpine, puis l'a quitté. Si vous avez remarqué, tout cela s'est produit très rapidement. Imaginez démarrer une machine virtuelle, exécuter une commande, puis la détruire. Maintenant, vous savez pourquoi on dit que les conteneurs sont rapides !
Essayons une autre commande.
Attendez, il ne s'est rien passé ! Est-ce un bogue ? Eh bien, non. Ces exécutions interactives se ferment après avoir exécuté les commandes scriptées, sauf si elles sont exécutées dans un terminal interactif. Pour éviter que cet exemple ne se ferme, vous devez utiliser docker run -it alpine /bin/sh
.
Vous êtes maintenant à l'intérieur du shell du conteneur et vous pouvez naviguer dans le conteneur. Si vous lancez exit
ou que vous tapez CTRL-D
, vous quitterez le shell du conteneur et il s'arrêtera également (attention il ne se détruira pas). Le conteneur est censé être éphémère.
Maintenant, voyons comment lister les conteneurs avec la commande docker ps
. docker ps
est la commande qui listera tous les conteneurs en cours d'exécution.
Comme vous n'avez pas de conteneur qui tourne actuelement (seulement des conteneurs qui ont été lancés mais qui sont maintenant stoppés), cette commande renvoie une liste vide. Essayons une petite variante : docker ps -a
$ docker ps -a
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
36171a5da744 alpine "/bin/sh" 5 minutes ago Exited (0) 2 minutes ago fervent_newton
a6a9d46d0b2f alpine "echo 'hello from alp" 6 minutes ago Exited (0) 6 minutes ago lonely_kilby
ff0a5c3750b9 alpine "ls -l" 8 minutes ago Exited (0) 8 minutes ago elated_ramanujan
c317d0a9e3d2 hello-world "/hello" 34 seconds ago Exited (0) 12 minutes ago stupefied_mcclintock
Vous voyez maintenant une liste de tous les conteneurs que vous avez exécutés. Remarquez que la colonne "STATUS" indique que ces conteneurs ont été arrêtés il y a quelques minutes. Vous vous demandez probablement s'il y a un moyen d'exécuter plus d'une commande dans un conteneur.
Essayons cela maintenant :
$ docker run -it alpine /bin/sh
/ # ls
bin dev etc home lib linuxrc media mnt proc root run sbin sys tmp usr var
/ # uname -a
Linux 97916e8cb5dc 4.4.27-moby #1 SMP Wed Oct 26 14:01:48 UTC 2016 x86_64 Linux
L'exécution de la commande run
avec l'option -it
nous connecte à un terminal interactif dans le conteneur. Maintenant, vous pouvez exécuter autant de commandes que vous le souhaitez dans le conteneur. Prenez le temps d'exécuter vos commandes préférées.
Astuce
run -it
est une commande très utile pour déboguer le bas niveau d'un conteneur.
Vous savez faire tourner un container et le lancer en mode interactif. Mais il manque une fonctionnalité essentielle lorsque l'on veut faire tourner un service. Pour l'illustrer lancer un nginx :
Question
Que se passe-t-il dans ce cas ?
Que se passe-t-il si vous fermez votre shell ou ctr+c par exemple (fermez votre shell relancez le et lancez un docker ps -a
)
En fait votre conteneur s'est lancé et ne vous rend pas la main et vous avez alors le log nginx sur votre shell. Lorsque vous quittez votre shell, le conteneur se stoppe et votre nginx se stoppe donc également.
Ce n'est pas un comportement souhaitable lorsque l'on veut lancer des services en tache de fond, c'est ce qu'on apelle un daemon. Docker nous permet de le faire avec une simple option -d
relancez votre conteneur Nginx en mode service
$ docker run -d --name mon-nginx registry.takima.io/school/proxy/nginx
b611eea1536bcfc79f87e1bfd57a3f10bbe4577f03e405329f5626cd66a64e54
Maintenant lancez un docker ps
. Vous verrez votre docker nginx tourner
Voilà docker run
n'a plus de secret pour vous, et c'est parfait car c'est probablement la commande que vous utiliserez le plus fréquemment. Il est judicieux de prendre le temps de vous familiariser avec elle. Pour en savoir plus sur run
, utilisez docker run --help
pour voir la liste de tous les indicateurs qu'elle prend en charge. Au fur et à mesure de votre progression, vous verrez quelques variantes de docker run
.
Pour la suite taguez votre image nginx :
A tout moment vous pouvez inspecter un container avec docker container inspect
, par exemple pour récupérer son status :
Success
Point cours pour voir les Network Docker
Les Network Docker
Faire tourner un applicatif c'est bien mais lorsque l'on fait du web c'est essentiel de pouvoir publier son application et que cette application bénéficie d'une connectivité (IP), mais c'est aussi essentiel d'isoler les conteneurs dans des réseaux séparés. Après tout c'est aussi l'une des promesses de docker l'isolation.
Objectif:
- Comprendre les concepts de base des réseaux Docker.
- Créer et gérer des réseaux Docker.
- Connecter des conteneurs à des réseaux personnalisés.
Vérifier les réseaux Docker existants
Pour lister les reseaux actuels :
$ docker network ls
NETWORK ID NAME DRIVER SCOPE
df8d9a03e3e1 bridge bridge local
f0b4def22265 host host local
a7cd984404b5 none null local
Ce sont les réseaux par défault. On peut créer autant de nouveau réseaux isolés que l'on souhaite et lorsque l'on créé un reseau il sera de type bridge par défaut
Lorsque l'on créer un conteneur il se trouve attaché par défaut au réseau nommé bridge
. On déconseille donc de l'utilser pour faire tourner nos applications.
Créer un réseau personnalisé
Créez un réseau Docker personnalisé en utilisant la commande docker network create
. Par exemple, créez un réseau nommé "app" :
Vous pouvez vérifier que le réseau a été créé en utilisant la commande docker network ls
.
Exécuter des conteneurs connectés au réseau personnalisé
Créez deux conteneurs connectés au réseau "app". Par exemple, nous pouvons créer un conteneur web et un conteneur de base de données :
Le conteneur webapp
est maintenant connecté au réseau `app``
Vérifier la connectivité
Vous pouvez maintenant vérifier si un conteneur présent sur ce réseau app
peut communiquer avec la webapp. Exécutez un conteneur de test connecté au même réseau :
À l'intérieur de ce conteneur de test, essayez de "pinguer" le conteneur webapp en utilisant leurs noms de conteneurs comme hôtes. Assurez-vous que la connectivité fonctionne avec un wget sur le port 80 par exemple .
$ wget webapp
Connecting to webapp (172.19.0.2:80)
saving to 'index.html'
index.html 100% |**********************************************************************************************| 615 0:00:00 ETA
'index.html' saved
$ cat index.html
Supprimer le réseau
Pour supprimer le réseau personnalisé que vous avez créé, utilisez la commande suivante :
Notes
Si un réseau est utilisé, impossible de le détruire.
Success
Point cours sur la publication des conteneurs
La publication
Nous avons isolé les conteneurs dans un réseau et c'est parfait pour la sécurité. Mais certains services sont plus utiles lorsqu'ils sont accèssibles. Nous allons donc voir comment publier un service sur le Host qui l'héberge.
Objectif :
- Comprendre comment publier des ports de conteneurs Docker.
- Tester l'accessibilité des applications via les ports publiés.
Vérification des ports existants
Avant de commencer, listez les conteneurs actuellement en cours d'exécution sur votre système à l'aide de la commande suivante :
Cette commande affichera les conteneurs actifs, mais notez qu'aucun port n'est actuellement publié pour eux.
Créer un conteneur avec des ports publiés
Créez un conteneur avec un serveur web Nginx et publiez son port 80 sur un port de votre machine hôte, par exemple, le port 8080. Utilisez la commande suivante :
Cela démarrera un conteneur Nginx avec son port 80 publié sur le port 8080 de votre machine hôte.
Accès à l'application via le port publié
Ouvrez un navigateur web et accédez à http://localhost:8080
. Vous devriez voir la page d'accueil Nginx, ce qui signifie que le serveur web du conteneur est accessible via le port publié.
Gestion des ports publiés
Pour afficher les ports publiés par un conteneur en cours d'exécution, utilisez la commande docker port
. Par exemple :
Arrêter et supprimer les conteneurs
Lorsque vous avez terminé, arrêtez et supprimez les conteneurs que vous avez créés :
Tip
rm -f est utile pour aller plus vite.
Success
Point cours sur les Volumes Docker
Les volumes Docker
placez vous dans un dossier /td-volumes
Création d'un Conteneur avec un Volume
Nous allons ici utiliser un bind volume : Il s'agit d'un volume monté depuis un dossier du host (celui qui lance les dockers)
-
Créez un répertoire vide sur votre système hôte pour servir de volume. Par exemple :
-
Créez un conteneur en utilisant la commande
docker run
avec un volume monté à partir du répertoire que vous venez de créer. Assurez-vous de remplacerchemin_vers_votre_volume
par le chemin absolu du répertoire que vous avez créé à l'étape précédente : !!! tip Si vous êtes bien dans le dossier utilisé la variables de dossier courrant$(pwd)
"$(pwd)"/mon_volume:/containerDir -
Vérifiez que le conteneur est en cours d'exécution en utilisant
docker ps
.
Utilisation du Volume depuis le Conteneur
-
Exécutez un shell interactif dans le conteneur que vous venez de créer :
-
À l'intérieur du conteneur, créez un fichier ou un répertoire dans le répertoire monté :
-
Quittez le shell du conteneur en utilisant
exit
.
Vérification de la Persistance des Données
-
Arrêtez et supprimez le conteneur :
-
Vérifiez que le répertoire et le fichier que vous avez créés sont toujours présents dans le répertoire du volume sur votre système hôte :
Création d'un Deuxième Conteneur avec le Même Volume
-
Créez un deuxième conteneur en utilisant le même volume que le premier :
-
Exécutez un shell interactif dans le deuxième conteneur :
-
Vérifiez que le fichier ou le répertoire que vous avez créé est présent dans le deuxième conteneur, même s'il s'agit d'un conteneur différent.
-
Quittez le shell du deuxième conteneur en utilisant
exit
.
clean
-
Supprimez le deuxième conteneur :
-
Supprimez le répertoire du volume sur votre système hôte :
Success
Point cours sur les Images Docker
Images Docker
Dans cette section, plongeons plus en profondeur dans ce que sont les images Docker. Vous allez construire votre propre image, utiliser cette image pour exécuter une application localement, et enfin, pousser certaines de vos propres images vers Docker Hub.
Les images Docker sont la base des conteneurs. Dans l'exemple précédent, vous avez pull une image nginx
depuis le registre et avez demandé au client Docker d'exécuter un conteneur basé sur cette image. Pour voir la liste des images disponibles localement sur votre système, exécutez la commande docker images
.
$ docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
dockersamples/static-site latest 92a386b6e686 2 hours ago 190.5 MB
nginx latest af4b3d7d5401 3 hours ago 190.5 MB
Vous aurez une liste différente d'images sur votre machine. Le TAG
fait référence à une version de l'image et l'image ID
est l'identifiant unique correspondant de cette image.
Pour simplifier, vous pouvez considérer une image comme un référentiel Git : les images peuvent être commitées avec des modifications et avoir plusieurs versions. Lorsque vous ne fournissez pas de numéro de version spécifique, le client par défaut est "latest" (dernière version).
Par exemple, vous pourriez extraire une version spécifique de l'image ubuntu
comme suit :
Si vous ne spécifiez pas le numéro de version de l'image, le client Docker utilisera, comme mentionné précédemment, une version nommée "latest" (dernière version).
Donc, par exemple, la commande docker pull
ci-dessous extraira une image nommée registry.takima.io/school/proxy/ubuntu:latest
:
Pour obtenir une nouvelle image Docker, vous pouvez soit l'obtenir depuis un registre (tel que le Docker Hub ou bien un registre personnel comme nous sommes en train de faire) soit la créer vous-même. Il existe des centaines de milliers d'images disponibles sur le Docker Hub. Vous pouvez également rechercher des images directement depuis la ligne de commande à l'aide de docker search
.
Une distinction importante concernant les images se situe entre les images de base (base images) et les images enfants (child images).
-
Les images de base sont des images qui n'ont pas d'images parent, généralement des images avec un système d'exploitation tel qu'Ubuntu, Alpine ou Debian.
-
Les images enfants sont des images qui se construisent sur des images de base et ajoutent des fonctionnalités supplémentaires.
Un autre concept clé est l'idée d'images officielles et d'images utilisateur (user images). (Les deux peuvent être des images de base ou des images enfants.)
-
Les images officielles sont des images vérifiées par Docker. Docker, Inc. sponsorise une équipe dédiée responsable de la révision et de la publication de tout le contenu des référentiels officiels. Cette équipe travaille en collaboration avec les mainteneurs de logiciels, des experts en sécurité et la communauté Docker élargie. Elles ne sont pas préfixées par un nom d'organisation ou d'utilisateur. Dans la liste des images ci-dessus, les images
python
,node
,alpine
etnginx
sont des images officielles (de base). Pour en savoir plus à leur sujet, consultez la documentation sur les images officielles. -
Les images utilisateur sont des images créées et partagées par des utilisateurs comme vous. Elles se construisent sur des images de base et ajoutent des fonctionnalités supplémentaires. Typiquement, elles sont formatées comme
utilisateur/nom-de-l'image
. La valeurutilisateur
dans le nom de l'image correspond à votre nom d'utilisateur ou d'organisation Docker Hub.
Créez votre première image
Maintenant que vous avez une meilleure compréhension des images, il est temps de créer la vôtre. Notre principal objectif ici est de créer une image qui isole une petite application Flask.
L'objectif de cet exercice est de créer une image Docker qui exécutera une application Flask.
Nous allons commencer par rassembler les composants pour un générateur aléatoire d'images de chats construit avec Python Flask, puis dockeriser cela en écrivant un Dockerfile. Enfin, nous allons construire l'image, puis l'exécuter.
Créez une application Python Flask qui affiche des images de chats aléatoires.
Dans le cadre de cet atelier, nous avons créé une petite application Python Flask amusante qui affiche une image de chat aléatoire au chargement - car, vous savez, qui n'aime pas les chats ?
Commencez par créer un répertoire appelé flask-app
où nous allons créer les fichiers suivants :
- app.py
- requirements.txt
- templates/index.html
- Dockerfile
Assurez-vous de vous déplacer vers cd flask-app
avant de commencer à créer les fichiers, car vous ne voulez pas ajouter tout un tas d'autres fichiers à votre image.
app.py
Créer le fichier python app.py avec ce contenu:
from flask import Flask, render_template
import random
app = Flask(__name__)
# liste des images
images = [
"https://c.tenor.com/GTcT7HODLRgAAAAM/smiling-cat-creepy-cat.gif",
"https://media0.giphy.com/media/10dU7AN7xsi1I4/giphy.webp?cid=ecf05e47gk63rd81vzlot57qmebr7drtgf6a3khmzvjsdtu7&rid=giphy.webp&ct=g",
"https://media0.giphy.com/media/S6VGjvmFRu5Qk/giphy.webp?cid=ecf05e478yofpawrhffnnvb3sgjkos96vyfo5mtqhds35as6&rid=giphy.webp&ct=g",
"https://media3.giphy.com/media/JIX9t2j0ZTN9S/200w.webp?cid=ecf05e47gk63rd81vzlot57qmebr7drtgf6a3khmzvjsdtu7&rid=200w.webp&ct=g"
]
@app.route('/')
def index():
url = random.choice(images)
return render_template('index.html', url=url)
if __name__ == "__main__":
app.run(host="0.0.0.0")
requirements.txt
Ce fichier requirements.txt référence les modules Python necessaire pour lancer notre app Python
templates/index.html
Créez le dossier templates
et créez dans ce dossier le fichier index.html avec le contenu suivant:
<html>
<head>
<style type="text/css">
body {
background: black;
color: white;
}
div.container {
max-width: 500px;
margin: 100px auto;
border: 20px solid white;
padding: 10px;
text-align: center;
}
h4 {
text-transform: uppercase;
}
</style>
</head>
<body>
<div class="container">
<h4>Cat Gif of the day</h4>
<img src="{{url}}" />
<p>
<small
>Courtesy:
<a
href="http://www.buzzfeed.com/copyranter/the-best-cat-gif-post-in-the-history-of-cat-gifs"
>Buzzfeed</a
></small
>
</p>
</div>
</body>
</html>
Rédigez un Dockerfile
Dernier fichier et pas des moindre le Dockerfile.
Nous voulons créer une image Docker avec cette application web. Comme mentionné précédemment, toutes les images utilisateur sont basées sur une image de base.
Étant donné que notre application est écrite en Python, nous allons créer notre propre image embarquant notre app Python basée sur Alpine. Nous allons le faire en utilisant un Dockerfile.
Tip
L'image Alpine
est souvent utilisé comme image de base car elle est très légère
Un Dockerfile est un fichier texte qui contient une liste de commandes que le daemon Docker appelle lors de la création d'une image. Le Dockerfile contient toutes les informations dont Docker a besoin pour exécuter l'application : une image Docker de base qui servira de socle , l'emplacement de votre code de projet, ses dépendances éventuelles, et les commandes à exécuter au démarrage.
C'est un moyen simple d'automatiser le processus de création d'images.
-
Créez un fichier appelé Dockerfile et ajoutez-y le contenu comme décrit ci-dessous.
Nous allons commencer par spécifier notre image de base en utilisant le mot clé
FROM
: -
La prochaine étape consiste généralement à écrire les commandes de copie des fichiers et à installer les dépendances nécessaire pour notre application. Mais d'abord, nous allons installer le package Python pip dans la distribution Linux Alpine. Cela n'installera pas seulement le package pip, mais aussi d'autres dépendances, y compris l'interpréteur Python. Ajoutez la commande RUN suivante :
-
Ajoutons les fichiers qui composent l'application Flask.
Installez toutes les dépendances Python nécessaires pour le bon fonctionnement de notre application. Cela sera accompli en ajoutant les lignes suivantes :
Copiez les fichiers que vous avez créés précédemment dans notre image en utilisant la commande COPY.
-
Spécifiez le numéro de port qui doit être exposé. Comme notre application Flask s'exécute sur le port
5000
, c'est ce que nous allons exposer. -
La dernière étape est de définir la commande pour lancer l'application :
python ./app.py
. Utilisez la commande ENTRYPOINT pour cela :Le but principal de
ENTRYPOINT
est d'indiquer au conteneur la commande qu'il doit exécuter par défaut lors de son démarrage.Tip
En vérité ENTRYPOINT servira à définir l'executable et le CMD servira à définir les paramètres de l'executable
-
Vérifiez votre Dockerfile.
Notre Dockerfile est maintenant prêt. Voici à quoi il ressemble :
# notre image de base FROM registry.takima.io/school/proxy/alpine:3.6 # Installer Python et pip RUN apk add --update py2-pip # Installer les modules Python nécessaires par l'application Python COPY requirements.txt /usr/src/app/ RUN pip install --no-cache-dir -r /usr/src/app/requirements.txt # Copier les fichiers nécessaires pour l'exécution de l'application COPY app.py /usr/src/app/ COPY templates/index.html /usr/src/app/templates/ # Indiquer le numéro de port que le conteneur doit exposer EXPOSE 5000 # Exécuter l'application ENTRYPOINT ["python", "/usr/src/app/app.py"]
Builder notre image
Maintenant que notre Dockerfile
est prêt, il est temps de builder notre application.
La commande docker build
s'occupe du travail de créer une image Docker à partir du Dockerfile.
Lorsque vous exécutez la commande docker build
, assurez-vous de remplacer <YOUR_USERNAME>
par votre nom d'utilisateur. Ce nom d'utilisateur devrait être le même que celui que vous avez créé lors de votre inscription sur Docker Hub. Si vous ne l'avez pas encore fait mettez le nom que vous souhaitez pour votre tag.
La commande docker build
est assez simple. Elle prend un nom de balise ou tag facultatif avec l'option -t
et l'emplacement du répertoire contenant le Dockerfile. Le point .
indique le répertoire actuel :
$ docker build -t <YOUR_USERNAME>/myfirstapp .
Sending build context to Docker daemon 9.728 kB
Step 1 : FROM alpine:latest
---> 0d81fc72e790
Step 2 : RUN apk add --update py-pip
---> Running in 8abd4091b5f5
fetch http://dl-4.alpinelinux.org/alpine/v3.3/main/x86_64/APKINDEX.tar.gz
fetch http://dl-4.alpinelinux.org/alpine/v3.3/community/x86_64/APKINDEX.tar.gz
(1/12) Installing libbz2 (1.0.6-r4)
(2/12) Installing expat (2.1.0-r2)
(3/12) Installing libffi (3.2.1-r2)
(4/12) Installing gdbm (1.11-r1)
(5/12) Installing ncurses-terminfo-base (6.0-r6)
(6/12) Installing ncurses-terminfo (6.0-r6)
(7/12) Installing ncurses-libs (6.0-r6)
(8/12) Installing readline (6.3.008-r4)
(9/12) Installing sqlite-libs (3.9.2-r0)
(10/12) Installing python (2.7.11-r3)
(11/12) Installing py-setuptools (18.8-r0)
(12/12) Installing py-pip (7.1.2-r0)
Executing busybox-1.24.1-r7.trigger
OK: 59 MiB in 23 packages
---> 976a232ac4ad
Removing intermediate container 8abd4091b5f5
Step 3 : COPY requirements.txt /usr/src/app/
---> 65b4be05340c
Removing intermediate container 29ef53b58e0f
Step 4 : RUN pip install --no-cache-dir -r /usr/src/app/requirements.txt
---> Running in a1f26ded28e7
Collecting Flask==0.10.1 (from -r /usr/src/app/requirements.txt (line 1))
Downloading Flask-0.10.1.tar.gz (544kB)
Collecting Werkzeug>=0.7 (from Flask==0.10.1->-r /usr/src/app/requirements.txt (line 1))
Downloading Werkzeug-0.11.4-py2.py3-none-any.whl (305kB)
Collecting Jinja2>=2.4 (from Flask==0.10.1->-r /usr/src/app/requirements.txt (line 1))
Downloading Jinja2-2.8-py2.py3-none-any.whl (263kB)
Collecting itsdangerous>=0.21 (from Flask==0.10.1->-r /usr/src/app/requirements.txt (line 1))
Downloading itsdangerous-0.24.tar.gz (46kB)
Collecting MarkupSafe (from Jinja2>=2.4->Flask==0.10.1->-r /usr/src/app/requirements.txt (line 1))
Downloading MarkupSafe-0.23.tar.gz
Installing collected packages: Werkzeug, MarkupSafe, Jinja2, itsdangerous, Flask
Running setup.py install for MarkupSafe
Running setup.py install for itsdangerous
Running setup.py install for Flask
Successfully installed Flask-0.10.1 Jinja2-2.8 MarkupSafe-0.23 Werkzeug-0.11.4 itsdangerous-0.24
You are using pip version 7.1.2, however version 8.1.1 is available.
You should consider upgrading via the 'pip install --upgrade pip' command.
---> 8de73b0730c2
Removing intermediate container a1f26ded28e7
Step 5 : COPY app.py /usr/src/app/
---> 6a3436fca83e
Removing intermediate container d51b81a8b698
Step 6 : COPY templates/index.html /usr/src/app/templates/
---> 8098386bee99
Removing intermediate container b783d7646f83
Step 7 : EXPOSE 5000
---> Running in 31401b7dea40
---> 5e9988d87da7
Removing intermediate container 31401b7dea40
Step 8 : CMD python /usr/src/app/app.py
---> Running in 78e324d26576
---> 2f7357a0805d
Removing intermediate container 78e324d26576
Successfully built 2f7357a0805d
Si vous n'avez pas l'image registry.takima.io/school/proxy/alpine:3.6
, le docker commencera par la télécharger, puis créera votre image. Par conséquent, la sortie de la commande sera sensiblement différente. Si tout s'est bien passé, votre image devrait être prête ! Exécutez docker images ls
et vérifiez si votre image (<YOUR_USERNAME>/myfirstapp
) apparaît.
Exécutez votre image
La prochaine étape de cette section consiste à exécuter l'image pour voir si elle fonctionne réellement.
$ docker run -p 8888:5000 --name myfirstapp YOUR_USERNAME/myfirstapp
* Running on http://0.0.0.0:5000/ (Appuyez sur CTRL+C pour quitter)
Accédez à http://localhost:8888, et votre application devrait être en ligne.
Appuyez sur le bouton "Actualiser" dans le navigateur Web pour voir quelques images de chat supplémentaires.
Docker Compose
Pourquoi faire ?
Maintenant que vous savez builder une image, lancer un conteneur, créer des volumes et des networks, vous allez vite vous apercevoir que cela peut être fastidieux de lancer toutes ces commandes une part une pour tout reconstruire ou bien tout supprimmer. Alors bien sur vous pourriez créer de multiple script bash par exemple pour lancer tout cela, puis un autre pour tous supprimer. Mais cela s'avère difficilement maintenanble et non scalable. Et en plus c'est une approche impérative. Heureusement Docker nous aide à éviter cela avec un outil : Docker Compose. Et en plus, c'est cool, car c'est du déclaratif. Et ça, lorsque l'on veut déployer des infras, on aime beaucoup.
Utilisation
Pour utiliser docker compose il vous faudra décrire votre stack à déployer (ensemble des objets docker : conteneurs, volume, network et bien d'autre).
-
placer vous dans un nouveau dossier et créez un fichier compose.yaml :
version: '3' services: webapp: image: registry.takima.io/school/proxy/nginx ports: - "8082:80" networks: - my-network volumes: - my-volume:/app/data environment: - DATABASE_URL=mysql://dbuser:dbpassword@db/dbname db: image: mysql:5.7 networks: - my-network environment: - MYSQL_ROOT_PASSWORD=rootpassword - MYSQL_DATABASE=dbname - MYSQL_USER=dbuser - MYSQL_PASSWORD=dbpassword volumes: - db-data:/var/lib/mysql networks: my-network: driver: bridge volumes: my-volume: db-data:
-
Lancez la stack
-
Verifiez l'état des objets
Question
Que constatez vous au niveau du nom des objets Docker
-
stopez la stack compose
-
supprimmez la stack compose
Note
L'option
--volumes
permet le purger les volumes. A utiliser avec parcimonie pour ne pas perdre de données !
Maintenant que vous savez comment exécuter des conteneurs Docker et créer des Dockerfiles, ou des stack entière avec compose, passons à la partie pratique.
© Takima 2023
"