Image de couverture de l'article Tuto Docker - Démarrer Docker (Partie 2)
Retour aux articles

L'agence

WanadevStudio

Tuto Docker - Démarrer Docker (Partie 2)

Grâce au précédent article, vous savez désormais ce qu'est Docker. Maintenant, venez apprendre à vous en servir grâce aux commandes principales et interactions de bases ! Tous sur la baleine !

Introduction

Cet article fait partie d'une série de billets portants sur Docker et son environnement :

Docker est un système permettant de gérer des containers (comme vous le savez déjà grâce à l'article sur la découverte de Docker), et là où Docker est très fort, c'est qu'il est capable de faciliter l'utilisation de parties les plus obscures.

Autour de notre baleine (Moby Dock pour les intimes). Docker repose sur une API RESTFul dont je vous parlerai dans un futur article. À cela, l'entreprise a associé un « docker-cli » permettant de facilement exécuter des commandes depuis notre terminal.

Depuis un terminal, si vous exécutez la commande docker, vous obtiendrez une liste de commandes exécutables, que voici :

$ docker
…
Commands:
    attach    Attach to a running container
    build     Build an image from a Dockerfile
    commit    Create a new image from a container's changes
    cp        Copy files/folders from a container's filesystem to the host path
    create    Create a new container
    diff      Inspect changes on a container's filesystem
    events    Get real time events from the server
    exec      Run a command in an existing container
    export    Stream the contents of a container as a tar archive
    history   Show the history of an image
    images    List images
    import    Create a new filesystem image from the contents of a tarball
    info      Display system-wide information
    inspect   Return low-level information on a container
    kill      Kill a running container
    load      Load an image from a tar archive
    login     Register or log in to a Docker registry server
    logout    Log out from a Docker registry server
    logs      Fetch the logs of a container
    port      Lookup the public-facing port that is NAT-ed to PRIVATE_PORT
    pause     Pause all processes within a container
    ps        List containers
    pull      Pull an image or a repository from a Docker registry server
    push      Push an image or a repository to a Docker registry server
    restart   Restart a running container
    rm        Remove one or more containers
    rmi       Remove one or more images
    run       Run a command in a new container
    save      Save an image to a tar archive
    search    Search for an image on the Docker Hub
    start     Start a stopped container
    stop      Stop a running container
    tag       Tag an image into a repository
    top       Lookup the running processes of a container
    unpause   Unpause a paused container
    version   Show the Docker version information
    wait      Block until a container stops, then print its exit code
…

Et voilà, avec cette liste, vous avez tout en main pour gérer vos containers et vos images. Facile, non ?

(Pour ceux qui utiliseraient boot2docker, je vous recommande de suivre la documentation et d'ouvrir un terminal dans lequel vous pourrez dialoguer avec votre Moby Docker),

Docker et ses images

Jusque là, je ne vous ai jamais parlé d'images. Je vous ai uniquement parlé de containers. Et pourtant, les images Docker sont d'une importance cruciale. En voici un peu plus sur ces images, si essentielles dans le fonctionnement de Docker.

Une image est un container statique. On pourrait comparer une image à une capture d'un container à un moment donné, d'une sorte de snapshot d'un de vos containers. Lorsqu'on souhaite travailler avec un container, on déclare forcément un container à partir d'une image.

De plus, les images Docker fonctionnent grâce à de l'héritage d'autres images. Votre image de Tomcat hérite elle-même de l'image de Java. Cette même image de Java qui a peut-être été construite à partir d'une Debian. Les héritages peuvent ainsi aller très loin ! Le container créé à partir d'une image contient le delta entre l'image de base à partir de laquelle le container a été instancié et l'état actuel. Grâce à ce système, la duplication de donnée est faible.

Le point technique !

Une image peut avoir été construite à partir d'une autre image qui elle-même a pu être construite à partir d'une autre image. Ce système fonctionne parfaitement grâce à un système d'empilement de containers. Par conséquent, lorsque vous construisez une image à partir d'une autre image vous stockez en réalité tous les containers qui vous ont permis de passer de votre image de base à votre image finale. Vous pouvez visualiser ce que je vous dis en exécutant la commande « docker history .

Vous pouvez à tout moment voir votre « bibliothèque » d'images avec la commande "docker images". Vous verrez, au fil des projets, vous aurez de plus en plus d'images. Utilisables comme "moules" à votre guise pour débuter vos projets ou, à minima, vos nouveaux containers.

Pour voir votre bibliothèque d'images :

$ docker images
REPOSITORY TAG IMAGE ID CREATED VIRTUAL SIZE

Voilà, vous venez d’interagir une première fois avec Docker. N'espérez pas voir quelque chose, par défaut vous ne possédez aucune image. Logique. Par chance, d'autres ont déjà des bases d'images prêtes à être utilisées !

Comment Récupérer (pull) une image Docker ?

Il existe une plateforme maintenue par Docker sur laquelle tout le monde peut pusher et puller des images. C'est un peu comme le GitHub des images Docker ! Dès maintenant, nous allons tenter de récupérer une image.  Il existe des images officielles pour tout et n'importe quoi ! Cette bibliothèque géante partagée, c'est le Docker Hub Registry !

Vous pouvez chercher une image d'une distribution ou d'un produit déjà installé. Commençons par trouver une image Docker que nous pourrions utiliser. Vous disposez de deux moyens pour en chercher une image : via l'interface web, ou via la commande "docker search".

Je vais utiliser la commande "docker search" (car je suis un barbu) pour trouver des distributions Debian, qui possèdent suffisamment d'étoiles (confiance des utilisateurs de la plateforme). La commande est la suivante.

$ docker search --stars=10 debian
NAME            DESCRIPTION                                     STARS     OFFICIAL   AUTOMATED
debian          (Semi) Official Debian base image.              248       [OK]       
google/debian                                                   25                   [OK]
tianon/debian   use "debian" instead - https://index.docke...   13

Et voilà les résultats disponibles avec mes critères. Commençons simple : ce qui m'intéresse, c'est une Debian officielle. Il y en a bien une, nommée debian, cotée 248 étoiles (!!) et flaguée [OK] sur l'attribut OFFICIAL. En avant, Moby Dock, pull cette image !

$ docker pull debian
…

Et voilà, après quelques secondes de téléchargement, vous disposez d'une image sur votre hôte. Vous pouvez d'ailleurs la voir en exécutant "docker images". Commande qui liste les images présentes sur votre machine.

Il existe un autre moyen moins utile au quotidien (mais qui peut tout de même servir), qui est d'importer une image avec la commande "docker load" depuis un fichier .tar.gz, exportée initialement par un Docker (celui d'un collègue, par exemple).

Comment créer une image ?

Désormais nous voulons apprendre à travailler de manière autonome et construire nos images à notre guise. Il existe plusieurs méthodes :

  1. le Dockerfile : déjà vu dans le premier article, il vous permet entre autres de partir d'une image initiale, de lancer des actions et de construire une nouvelle image.
  2. de lancer un container, effectuer des actions soit-même et commiter (avec la commande "docker commit") les modifications dans une nouvelle image.

Aujourd'hui je ne vais pas détailler la deuxième méthode, qui pour moi est moins utile dans un premier temps. A titre personnel, je me sers de cette méthode pour historiser mes personnalisations. Cela me permet de garder des états étape par étape de ma customisation de containers, afin de pouvoir repartir d'une étape bien précise, par exemple (d'où l'utilisation du terme snapshot utilisé plus haut).

Les différences entre un container et son image peuvent être vues grâce à la commande "docker diff".

Créer une image avec un Dockerfile

Ce fichier comporte un mélange d'instructions et de métadonnées. Grâce à ce ficher, vous donnez la recette pour que Docker puisse construire votre image. Le site officiel décrit bien évidemment l'intégralité des instructions qui peuvent être réalisées.

Commençons par créer un fichier nommé Dockerfile (sans extension ! Le nom de ce fichier n'est pas négociable) dans le dossier de notre choix, et indiquons lui quelles sont les prérogatives pour la création d'une nouvelle image. Pour notre exemple, nous souhaitons partir d'une Debian Wheezy (ou Debian 7), dans laquelle nous ajoutons Nginx.

Ligne par ligne, détaillons notre futur Dockerfile :

1 - J'indique la distribution de départ avec la ligne

FROM debian:wheezy

2 - Je nomme la personne qui à écrit ce Dockerfile, ici c'est moi. Grâce à la ligne

MAINTAINER Baptiste Donaux <bdonaux@wanadev.fr>

3 - Je recherche les paquets disponibles et j'installe Nginx.

RUN apt-get update \
    && apt-get install -y \
        nginx

4 - Je copie successivement les configurations et scripts de mon système hôte vers mon image

COPY nginx.conf /etc/nginx/nginx.conf
COPY service_start.sh /home/docker/script/service_start.sh

5 - J'applique les droits pour exécuter mon script

RUN chmod 744 /home/docker/script/service_start.sh

6 - Je définie un point d'entrée : le premier script qui va se lancer au démarrage du container

ENTRYPOINT /home/docker/script/service_start.sh

7 - Le dossier dans lequel je serai quand j'exécuterai un nouveau container sera WORKDIR

WORKDIR /home/docker

Nous avons toutes les lignes pour faire notre Dockerfile. Le voilà en version complete :

FROM debian:wheezy

MAINTAINER Baptiste Donaux <bdonaux@wanadev.fr>

RUN apt-get update \
    && apt-get install -y \
        nginx

COPY nginx.conf /etc/nginx/nginx.conf

COPY service_start.sh /home/docker/script/service_start.sh
RUN chmod 744 /home/docker/script/service_start.sh

ENTRYPOINT /home/docker/script/service_start.sh
WORKDIR /home/docker

Construire une image depuis un Dockerfile

Maintenant que nous avons un Dockerfile, nous voulons créer notre image. Et la commande magique est... « docker build » !

$ docker build .

Lorsque vous exécutez « docker build », vous devez spécifier le chemin du Dockerfile (d'où le point à la fin de la commande si vous lancez la commande depuis le même endroit).

Durant la construction vous allez voir défiler toutes les étapes s'exécuter les une après les autres. Le premier lancement est long, car aucune des étapes n'a été déjà appelée. Lors d'un second build, vous verrez que les étapes sont expédiées à grande vitesse ! (Essayez, pour voir !). Tout ça à condition que les étapes précédentes n'aient pas été modifiées dans votre Dockerfile, bien sûr !

Évidemment, Docker historise toutes les actions qu'il réalise (chaque instruction réalisée dans un Dockerfile est stockée dans un container intermédiaire). C'est également ce principe qui est utilisé pour réaliser des héritages entre images. Si les instructions sont inchangées et que leur ordre est identique à la précédente fois, elles ne sont PAS régénérées car Docker sait utiliser son cache et ré-utiliser les actions déjà réalisées. Fortiche, la baleine !

Explication : comment fonctionne le cache Docker ?

Le cache que « docker build » utilise n'est pas magique (même si ça en a l'air), mais il est facile à comprendre.

Plus haut, je vous ai vaguement parlé de la commande docker-commit qui vous permet de gérer des états de vos images en sauvegardant les changements d'un container dans une nouvelle image. Par défaut, quand vous faites un docker-build, chaque étape (chaque instruction de votre Dockerfile) est stocké dans un container intermédiaire (vous pouvez voir toutes les étapes de la construction d'une image en utilisant la commande docker-history). Docker possède une toutouille interne permettant de manager ses containers internes de manière à proposer les meilleurs performances lors de la construction d'une image. Héritage, historisation, vous vous souvenez ;) ?

Tagger une image ou sortir vos images de l'anonymat

Toute image ou tout container possède un identifiant unique. Nous pourrions utiliser ces identifiants unique, mais Docker Inc a prévu une fonctionnalité pour tagger nos images ainsi que nos containers afin de les réutiliser plus facilement.

Voici comment nommer vos images :

  1. Donner un nom à la construction de l'image avec l'option --tag
  2. Utiliser la commande docker-tag
  3. Nommer votre image au moment de l'utilisation de docker-commit

Exemple plus concret : création d'une image grâce à la commande docker-build et de son option --tag

$ docker build --tag="myImage[:myTag]"

Et voilà, faites désormais un docker-images et vous votre image correctement taggée apparaîtra dans votre liste !

Le point technique !

Les images peuvent avoir autant de noms et autant de tags que vous voulez. D'ailleurs l'image officielle de Debian Wheezy peut être trouvée sous le nom debian:7, debian:latest ou encore debian:wheezy. Dans ce cas, nous avons appliqué plusieurs tags sur un même nom d'image, mais peut-être voulez-vous appeler cette image avec un autre nom.
default                         debian                 c90d655b99b2
debian                          7.8                    c90d655b99b2
debian                          latest                 c90d655b99b2
debian                          wheezy                 c90d655b99b2
debian                          7                      c90d655b99b2
Ici vous voyez que l'image identifié par c90d655b99b2 est également identifié par default:debian.

Gestion des containers

Maintenant que la gestion des images n'est plus un problème pour vous, parlons un peu des containers.

Définir le fonctionnement d'un container

Nous en avons déjà parlé au-dessus, un container incarne la notion d'environnement. Dans Docker, même les images sont des containers, mais la différence entre une image et un container est dûe aux comportements.

Les images sont statiques ; on n'écrit pas directement dans une image. On déclare un container À PARTIR d'une image. Ce container va vivre et contenir les différences réalisés par rapport à l'image de base. Vous suivez ?

Un container contient également d'autres éléments, il stocke des paramètres d'exécutions, comme par exemple le mappage de port, les dossiers à partager.

Le point technique !

Actuellement on applique des paramètres à un container comme le forward de port, le partage de dossier… Mais il n'est pas possible de changer à chaud ses paramètres. Docker Inc. travaille également sur la possibilité de changer à chaud ses variables. Actuellement, le seul moyen pour nous de changer les paramètres est de :
  1. Enregistrer son container comme image (docker commit)
  2. Lancer un container à partir de la nouvelle image avec l'intégralité des paramètres que vous souhaitez utiliser.

Faisons ensemble un exercice.

Déclarer un container

Nous avons normalement une image debian avec plusieurs tags sur notre machine grâce à l'image créée plus haut. Déclarons un container.

$ docker run debian:wheezy

Et voilà, vous avez exécuté un container depuis une image Docker ! Avec cela, ne pensez pas faire des choses dingues, mais c'est un début. Si vous avez l'impression que cette commande n'a rien fait, vous pouvez voir avec la commande "docker ps -l" que des choses se sont passées :

$ docker ps -l
CONTAINER ID        IMAGE               COMMAND             CREATED             STATUS                     PORTS               NAMES
9b4841d73b6e        debian:7            "/bin/bash"         3 seconds ago       Exited (0) 3 seconds ago                       furious_hopper

Ce retour indique qu'un container nommé "furious_hopper" identifié par l'ID 9b4841d73b6e, a lancé la commande /bin/bash depuis une image debian:7 et s'est terminé avec le code retour 0. (Notez que Docker sait nommer ses containers de façon originale ! Ici furious_hopper !)

Même si votre container est éteint (statut Exited), celui-ci n'est pas supprimé, il est stocké (c'est important pour la suite). Vous pouvez d'ailleurs afficher tous les containers (ceux en cours et ceux stoppés) en utilisant la commande "docker ps -a".

Désormais, nous voulons interagir avec notre container. Pour cela, nous allons devoir utiliser quelques options de la commande "docker run", que voici :

$ docker run --tty --interactive debian:7

Vous devriez être dans un magnifique container avec un bash prêt à répondre. Vous remarquerez le temps de lancement est assez faible. Mais qu'avons-nous fait ? Détaillons ce qu'elle veut dire :

  • L'option --tty permet d'attacher la console à notre console actuelle et de ne pas perdre le focus. C'est grâce à cette option que votre container ne va pas se terminer.
  • L'option --interactive vous permet de dialoguer avec votre container. Sans cette option, tout ce que vous taperez dans votre console ne sera pas transmis au bash du container.

Dans notre cas, la commande lancée a été /bin/bash mais il ne s'agit pas d'un hasard. Lors de la déclaration d'une image (dans son Dockerfile), vous pouvez spécifier certaines metadatas comme CMD qui vous permettent de donner une commande par défaut si aucune n'est spécifiée.

Si vous aviez voulu lancer une autre commande que /bin/bash, vous auriez pu faire comme ceci au moment de la déclaration de votre container :

$ docker run debian:7 echo Docker is fun

Et voilà, votre container a été créé et a lancé la commande que vous avez donné ("echo Docker is fun"), puis s'est terminé car aucune commande exécutée n'a pris le focus de la console.

Utiliser un container

Maintenant que vous savez lancer des commandes dans un container, allons un peu plus loin avec un exemple simple.

Un container est l'équivalent d'un Filesystem. Aussi, mon projet Symfony utilise une base de données. Puisque ma base de données va changer, nous ne voulons pas perdre nos données (enfin, j'imagine ;) !). Ce serait le cas si vous faisiez un "docker run" à chaque fois que vouliez lancer votre service de base de données. Pourquoi ? Car comme vu plus haut, le "docker run" lance un nouveau container. Un nouveau ! Il n'utilise pas celui qui avait déjà été créé auparavant ! Voyons comment faire pour ne pas avoir ce problème.

Détaillons le fonctionnement de "docker run"

Au début, c'était LA (!) commande que j'utilisais tout le temps. Maintenant plus vraiment. Que fait vraiment le "docker run" ? Cette commande exécute successivement deux autres commandes auxquelles vous avez accès : "docker create" et "docker start". Détaillons les ensemble.

docker-create

"docker create" est une commande indispensable ! Si vous faites un man, vous remarquerez que celle-ci contient les mêmes options que "docker run". Avec cette commande, vous allez créer un container à partir d'une image en lui donnant des paramètres d'exécution.

  • mappage des ports
  • partage des dossiers

Parmi les données paramétrables, vous allez pouvoir donner un nom à votre container. Docker donnera toujours un nom à votre container (furious_hopper, vous vous souvenez ?), mais il vous sera plus simple de retrouver le container de votre projet avec un nom adéquat plutôt que "condescending_wozniak" ! XD

Voici la commande complète pour créer un container, celle que vous utiliserez désormais !

$ docker create --tty --interactive --name="wonderful_mobidock" debian:7

Le retour de cette commande devrait être une suite indigeste de caractères (indiquant l'ID donné à votre container).

docker-start

Notre container est désormais créé grâce à la commande "docker create". D'ailleurs en faisant un "docker ps -a" vous devriez le trouver.

Maintenant que vous avez créé votre container et que vous l'avez configuré, vous pouvez le lancer avec la commande "docker start".

$ docker start wonderful_mobidock

Par défaut, "docker start" ne vous attache pas la console, mais vous pouvez le spécifier avec l'option --attach.

$ docker start --attach wonderful_mobido

Voilà qui est simple non ?

Ré-utiliser un container

Notre container est lancé et nommé. Notre base de données vit dans notre container, et d'une fois sur l'autre nous ne voulons pas perdre nos données (ce qui serait dommageable avouons-le). La commande "docker stop" permet d'éteindre proprement un container (l'utilisation de "docker kill" doit être limitée).

Si plus tard, vous voulez relancer ce wonderful_mobydock  et récupérer vos données, exécutez "docker start" !

Conclusion

Désormais, vous êtes capable de créer une image et de gérer vos containers simplement en les nommant, les créant et en les arrêtant. L'intégralité des commandes et des options n’ont pas été détaillées ici mais vous devriez désormais disposer des bonnes pratiques pour commencer à utiliser Docker. Le manuel est votre ami, et Docker grandit vite, tenez vous au courant !

Si vous avez des questions, n'hésitez pas à nous à les poser sur la zone de commentaires juste en dessous ! N'hésitez pas non plus à nous suivre sur Twitter et sur Facebook pour être averti de la suite de ce billet, second épisode d'une série de 4 articles !

Commentaires

Photo de Randy Marsh auteur du commentaire

Randy Marsh

Il y a 8 ans

Exellent article !!!
Merci beaucoup, cela m’a enormement aider a comprendre le concept et l’utilisation de docker !
Certianement le meilleur article du genre en francais !
Bonne continuation !
Bonjour Randy, Merci beaucoup pour tes encouragements. N’hésites pas à revenir ici si tu as besoin d’aide sur une autre partie de Docker
Photo de Ludovic auteur du commentaire

Ludovic

Il y a 8 ans

Super articles !
Merci, ça me motive pour tester la chose !
Un grand merci, et bon courage. N’hésites pas à revenir vers nous si besoin.
Photo de hadf auteur du commentaire

hadf

Il y a 8 ans

Très didactique et bien détaillé. C’est une très bonne introduction à Docker, j’ai beaucoup appris.

Juste une petite remarque. En continuant mes recherches sur Docker, j’ai vu la notion de volume. Je pense que les données ne devraient pas être stockées dans le conteneur mais sur le système hôte, et rendues accessibles en montant le répertoire de données dans le conteneur. Comme ça, si on a besoin de changer le conteneur pour monter en version, on garde les données.

Merci pour ce tutoriel :)
Bonjour et encore une fois, merci pour vos retours. Nous sommes tous contents de pouvoir vous proposer un tutoriel d’initiation répondant à vos interrogations !

Concernant ta remarque, tu as ENTIÈREMENT raison ! La notion de volumes a toujours existé dans Docker, mais celle-ci s’est encore plus affirmée depuis que l’on peut gérer les volumes manager par Docker. Lorsque nous avons rédigé cet article, les volumes non partagés étaient gérés et persistés par le Docker Engine. Il était alors difficile de dealer avec ces datas. Depuis, la commande « docker volume » a été ajoutée et tu peux facilement manager aussi bien les volumes non partagés, que des volumes créés manuellement dont tu déciderais qu’ils doivent être partagés entre plusieurs containers.

Dans la rubrique « Ré-utiliser un container », il est vrai que mon exemple de base de données mériterait une mise à jour. Aujourd’hui lorsque nous déclarons une base de données nous partageons toujours de volumes des datas (pour mysql il s’agit de /var/lib/mysql) dans un dossier de notre projet. Cela nous permet de facilement gérer les fichiers, dans un dossier spécifique, ainsi que de gérer les backups.

Espérant avoir éclairci tes interrogations sur les volumes, nous t’invitons à revenir vers nous en cas de nécessité.

Baptiste
Photo de cod auteur du commentaire

cod

Il y a 8 ans

Super article (très bien construit) !!
J’attends le next
Photo de Michel auteur du commentaire

Michel

Il y a 8 ans

Très bon article sur Docker qui m’a permis de bien appréhender les bases. Y a plus qu’a… comme on dit ^^
De la part de toute l’équipe, nous te souhaitons de bonnes Dockerization :)

N’hésites pas à revenir vers nous si nécessaire, à partager cet article ou à nous suivre sur Twitter (@Agence_WanaDev).

Baptiste
Photo de Pierre auteur du commentaire

Pierre

Il y a 8 ans

Salut Baptiste,

Super tuto, ça m’a permis de comprendre le fonctionnement de Docker.

Je suis actuellement en train de développer une application personnel, est-ce que tu me conseillerais d’utiliser Docker sur mon environnement de dev (je bosse sur mac) sachant que je suis seul pour bosser sur ce projet ?
Et pour mon environnement de production, j’ai un vps avec debian dessus, est-ce que Docker est intéressant et ne risque pas de diminuer les performances du serveur?

En tout cas merci pour ce tuto ! :)

Bonjour Pierre,

Merci pour ton retour !

Il n’y a pas d’utilisation abusive de Docker. Même si tu es tout seul à développer une application je te conseille d’utiliser Docker. Pourquoi ?
– Ton environnement est parfaitement défini. Cela te permet d’exécuter ton projet sur différentes machines/OS/versions sans modifier le comportement de ton application
– Tu peux facilement déployer sur ton serveur. Tu connais les versions de tes services et comment ils doivent être configuré.

Pour ton serveur de production, c’est un peu la même histoire que pour l’environnement de dev. Si tu déploies avec Docker tu t’assures d’avoir exactement la même version en dev qu’en production. Tu mets à jour facilement (upgrade de tes services par exemple) et tu limites l’utilisation de PPA (par exemple). Tu limites les installations de paquets (via apt-get/dpkg) et par conséquent, la maintenance propre à ta machine se limitera au FIX de sécurité. Quant aux performances, le lancement de containers n’a pas de réel surcoût pour ta machine car les containers sont gérés directement par le Kernel (>= 3.10). Les processus exécutés à l’intérieur de tes containers restent de simples processus et donc cela ne change rien pour toi. Pour ma part, je l’utilise sur mon serveur et je suis assez content de pour faire tourner des versions différentes de chaque soft en même temps.

Vers l’infini et au-delà
Plus tard, dans le cas où tu est besoin de monter en puissance suite à une monté en charge, tu peux facilement créer un cluster de Docker (swarm) et scaler/déporter chacun de tes services sur des machines séparées

Photo de Pierre auteur du commentaire

Pierre

Il y a 8 ans

Merci pour ce retour rapide.
Je vais donc mettre en place Docker à la fois sur mon poste de développement et mon serveur de production
Photo de Shivaan auteur du commentaire

Shivaan

Il y a 8 ans

Merci pour ce tuto.
J’aimerais bien me mettre à docker, mais je ne sais pas quelle solution choisir. il faut prendre quoi ? datacenter ? cloud ? compose ? machine ?
Existe t-il des versions gratuites pour s’entrainer sans mettre en production ?
J’avoue que leur site me perd un peu…
Bonjour Shivaan et merci pour ton retour. Tu peux tout à fait utiliser les solutions que tu as cité mais tu peux également te servir de Docker dans un contexte plus simple avec simplement le Docker Engine sur un serveur à toi. Concernant les solutions Docker {Datacenter,Cloud}, il s'agit de produits très intéressant mais destiné à des infrastructures ayant des contraintes techniques comme du Load Balancing, Scalability, … UCP (Universal Control Panel) est peut également être intéressant pour manager un parc de containers (CaaS). Je te conseille vivement d'utiliser Compose pour facilement manager tes applications. Il s'agit d'un outils complet qui te permettra de facilement déployer une application sur un node et de déployer cette même application au sein d'un cluster Swarm dans le futur. Pour Docker Machine, il s'agit plus d'un outil de provisionning qui pourrait être utile le jour où tu voudras créer des VMs sur des services telle que Google Engine, vSphere… Pour commercer simplement, docker {engine,compose} sont suffisant pour simplement commencer. Cordialement, Baptiste
Photo de Guichou auteur du commentaire

Guichou

Il y a 8 ans

Slt Baptiste

Merci pour ce super article, très bien expliqué et progressif !

Hate de le mettre en place

Une question, j'ai un site perso développé en Symfony2 pour pouvoir l’héberger à moindre coût sur OVH mais que je laisse un peu vivoter car je suis plutôt du monde java et n'ai pas bcp de temps en ce moment.

Je voudrai le ré-implémenter en java et le dockeriser ce qui me permettrait de travailler un peu plus souvent dessus mais ou l’héberger ensuite?

je me suis rapproché d'OVH pour voir leurs offres mais ils m'ont dit pas possible sur les offres mutu.

Connaîtrais-tu des solutions pour héberger des appli docker dans les 3 ou 4 € / mois?



Enfin en lisant les commentaires tu disais que c'était cool de dev et déployer en prod sur docker.

Mais dans l'article il m'avait semblé que tu disais développer sur docker iso prod et livrer sur la prod (unix).

=>Du coup: Prod docker ou Native ? (docker permet monter en charge si besoin,  donc mieux a mon sens) non?

Bonne continuation!


Bonjour et merci pour ton retour !

Les serveurs mutualisés ne supportent pas Docker car il s'agit uniquement d'un dépôt de fichier. Par contre, on peut désormais utiliser Docker sur les VPS OVH ce qui est une bonne chose. Tu peux prendre un hébergement peu onéreux.

Dans notre environnement de travail, on met en place Docker sur notre environnement Linux (uniquement car pas besoin de VM pour lancer Docker) de développement et on travaille actuellement sur mettre Docker pour nos projets en dev. Concernant la production, on s'assure d'avoir un minimum de compatibilité (version de PHP…).

Cordialement, Baptiste

Photo de omar-yann DIABIRA auteur du commentaire

omar-yann DIABIRA

Il y a 8 ans

Bonjour,


L'article à l'air hyper bien et instructif, mais je bloque, et je me demande si j'ai un problème ou s'il manque quelquechose...

COPY nginx.conf /etc/nginx/nginx.conf
COPY service_start.sh /home/docker/script/service_start.sh

OK, mais d'ou viennent les fichiers nginx.conf et service_start.sh ?
Faut-il installer nginx en local, recupérer les fichiers... Je suis perdu et j'ai l'impression que j'ai loupé une étape.

Merci pour la future réponse. 

OYD.



Bonjour et merci pour ton retour.

Les instructions COPY permettent de copier des fichiers de ta machine vers ton image. Dans le cas présenté, nginx.conf et service_start.sh sont des fichiers qui sont présent à la racine de ton projet.

Il s'agit d'un exemple, peut-être que dans ton cas tu n'auras pas besoin de copier ces fichiers.

Pour commencer, essaies de lancer des commandes simples et les besoins vont ensuite venir.

N'hésites pas à revenir vers nous si besoin.

Baptiste

Photo de Julien auteur du commentaire

Julien

Il y a 8 ans

Bonjour,

Merci beaucoup pour votre article.

j'essaye d'installer un logiciel sur un container Redhat. mais quand je lance le .sh, il ne trouve pas le gunzip.

Il m'affiche le message suivant: "Sorry, but I could not find gunzip in path. Aborting"

gunzip is install in /usr/bin

PATH=/usr/loal/bin:/usr/bin:/bin:/usr/local/sbin:/usr/sbin

SHELL= /bin/bash

path= (vide) 

Je suppose que le script utilise la variable d'environnement SHELL, ma question est comment puis-je modifier une Variable d’environnement de mon container Redhat et qui la sauvegarde si je redémarre (start/stop) le container.

Merci d'avance

Bonjour et désolé pour le temps de réponse !

Tu peux te servir de ton container de la même manière qu'une machine « classique ». Tu dois donc pouvoir exporter ta variable avec export.

Cordialement, Baptiste

Photo de MrFranck auteur du commentaire

MrFranck

Il y a 7 ans

L'introduction etait très claire et les étapes de cette deuxième parties sont très bien détaillées.

C'est parti pour les commandes :)


Merci beaucoup pour ce beau tutoriel.

MrFranck

Grand merci pour tes encouragements ! N'hésites pas à revenir vers nous si tu as des questions et à nous suivre sur Twitter.

Baptiste

Photo de MedAmine auteur du commentaire

MedAmine

Il y a 7 ans

merci beaucoup

c'est vraiment utile,

et s'il est possible est ce que tu peux nous faire un tuto sur docker swarm svp 

Bonjour et merci pour tes retours !

Swarm a été déprécié. Pour remplacer cette brique externe, SwarmKit a été développé et intégré au sein du core de Docker. Celle-ci est particulièrement bien pensée et propose bien plus de fonctionnalités que la première version de Swarm. Les mécanismes sont assez différents et les outils s'étoffent de jour en jour pour proposer une solution native qui pourrait remplacer les Rancher et Kubernetes.

Compose était jusqu'il y a peu dépourvu d'options pour déployer sur un cluster. C'est désormais corrigé mais de nombreuses autres fonctionnalités seront rapidement intégrées.

Voici la documentation référence à suivre

Bonne chance, Baptiste

Photo de abdellah auteur du commentaire

abdellah

Il y a 7 ans

Merci bcp baptiste pour Ce trés bon tuto

j'ai par contre une question

c quoi les avantages qu'a docker sur les unikernel ou le contraire

est ce que c mieux d'utiliser unikernel ou docker pour les applications

et si tu as un bon tutoriel bien expliqué comme celui ci sur les unikernel je serai tres reconnaissant

Merci d'avance


Bonjour et merci pour l'intérêt que tu portes à notre article !

Docker est le système de "containerisation". Il permet de déployer des applications (image) via des containers. Unikernel est une société qui a été intégrée en 2016 au sein de Docker. Unikernel n'est pas un système de container mais une brique permettant d'intégrer un sein du kernel de la machine certaines fonctionnalités nécessaire à l'éxecution des applications. Les containers utilisent le kernel de la machine, et de manière à diminuer la consommation mémoire, limiter les fails et améliorer les performances générales de la machine, Unikernel propose de compiler un kernel lite.

Pour convaincre les entreprises de l'IT d'utiliser Docker pour déployer leurs applications, Docker souhaite améliorer son écosystème avec les compétences d'Unikernel.

J'espère avoir pu répondre à tes questions et t'avoir éclairer !

Cordialement, Baptiste

Photo de LAHLOUHI auteur du commentaire

LAHLOUHI

Il y a 7 ans

merci beaucoup baptiste ;)

Photo de LE CRAVER auteur du commentaire

LE CRAVER

Il y a 6 ans

docker search --stars=10 debian

Flag --stars has been deprecated, use --filter=stars=3 instead

Pour info ;-)

Photo de yassine auteur du commentaire

yassine

Il y a 6 ans

Hello merci pour ce tuto excellent ;-)

J’ai profité de ce tutoriel pour me mettre à Docker, mais je suis confronté à quelques problèmes, comme je n’ai trouvé nul part mes réponses, j’essaye ici ^^ »

Tout d’abord, l’ENTRYPOINT… J’ai essayé de mettre un script simple avec un « service nginx start », le script fonctionne bien dans le container mais une fois en ENTRYPOINT impossible de démarrer le container, attaché ou pas, il démarre et s’arrête juste après… (sans le ENTRYPOINT il démarre correctement)

Mon deuxième problème est avec les socket unix dans les containers… J’ai installé nginx, php-fpm et mysql dans un container, mais impossible des les utiliser avec la configuration de base.
Le dossier /var/run est presque vide, les fichiers mysqld.sock, php-fpm.sock sont introuvables… de ce que j’ai lu j’ai l’impression que les unix sock ne marche pas dans les container, c’est bien ça ? (si oui ça veux dire qu’il est obligatoire de changer la configuration de pas mal de paquet pour se passer des sockets unix et passer par tcp)

Merci

Nous sommes très content de pouvoir répondre à toutes tes questions si cela te permet d’avancer rapidement sur cette technologie.

Premièrement, l’ENTRYPOINT. Dans ton cas, ton container fonctionne parfaitement. L’ENTRYPOINT exécute « service nginx start » mais dans la mesure où cette commande ne garde pas la main, aucun proccess ne garde la main sur le container, ce qui explique que celui-ci s’éteigne dans la foulé. La solution aurait été d’exécuter immédiatement l’exécutable de Nginx (/usr/bin/nginx) sans passer par un gestionnaire de processus.
Sur certaines images, supervisor est choisie pour manager plusieurs processus simultanément.

le script fonctionne bien dans le container mais une fois en ENTRYPOINT impossible de démarrer le container

Cela s’explique facilement. Lorsque tu lances ton container, tu possèdes un bash qui est lui-même en processus. Si tu kill ce processus, ton container s’éteint.

Ensuite, le problème des sockets Unix. À mes débuts je me suis aussi retrouvé confronté à ce problème. Il faut repenser ta manière de penser. Les processus (Nginx, FPM, MySQL) ne « dealent » pas toujours sur la même machine (un container étant comme une machine). On doit donc abandonner l’idée d’utiliser dans fichier un guise de socket mais de passer par les ports (IP + port). Puisque tu as essayé de créer tes propres images, par défaut, FPM utilise une socket fichier. MySQL n’écoute que localhost dans sa configuration de base.

Tu dois donc modifier leur fichier de configuration respectif pour qu’ils écoutent l’intégralité du réseau.

Dans la mesure où tu as essayé de créer tes propres images, il est bien d’être confronter à ces problèmes récurrents pour mieux aborder les futures problématiques. Une fois que tu auras pris la main sur la création d’image, il sera préférable que tu utilises des images officielles (présentes sur le Docker Hub). Celle-ci propose des configurations propres et prêtes à être utiliser, ainsi que des scripts facilitant la mise en place des services. (MySQL propose la création d’une base de donnée facilement via les variables environnements).

Nous restons à ta disposition pour éclaircir d’autres points si nécessaire.

Espérant avoir répondu à tes questions, bonne continuation et bonne année
Baptiste