virli/tutorial/1/dockerfile.md

172 lines
4.5 KiB
Markdown
Raw Normal View History

2015-10-22 03:25:20 +00:00
\newpage
2016-09-08 01:44:20 +00:00
`Dockerfile`
============
2015-10-22 03:25:20 +00:00
## Mon premier conteneur ... par `Dockerfile`
Pour construire une image, vous n'êtes pas obligé de passer par une série de
commits. Docker dispose d'un mécanisme permettant d'automatiser la construction
de nouvelles images. Vous pouvez arriver au même résultat que ce que l'on a
réussi à faire précédemment en utilisant le Docker file suivant :
```
FROM ubuntu:latest
RUN apt-get update
RUN apt-get install -y nano
```
La syntaxe d'un `Dockerfile` est simple, le premier mot de chaque ligne est
l'intitulé d'une instruction (que l'on écrit généralement en majuscule), elle
est suivie de ses arguments.
Dans notre exemple, nous utilisons `FROM` qui indique une image de départ à
utiliser ; `RUN` est une commande qui sera exécutée dans le conteneur, dans le
but de le construire.
Pour lancer la construction de la nouvelle image, créer un nouveau dossier ne
contenant que votre fichier `Dockerfile`, placez-vous dedans, puis utilisez la
commande `build` :
```
docker build --tag=my_editor .
```
Une fois la construction de l'image terminée, vous pouvez la lancer et
constater l'existence de notre éditeur favori :
```
docker run -it my_editor /bin/bash
```
## `RUN` dans le `Dockerfile`
2016-09-08 01:44:20 +00:00
Dans un `Dockerfile`, chaque ligne est exécutée indépendamment des
autres et correspondra à une nouvelle couche de notre image.
Cela signifie que l'exemple suivant **ne fonctionne pas** :
2015-10-22 03:25:20 +00:00
```
COPY db.sql /db.sql
RUN service mysqld start
RUN mysql -u root -p toor virli < /db.sql
```
Cet exemple ne fonctionne pas car le serveur MySQL est lancé dans le premier
RUN, n'est plus lancé au moment du deuxième RUN. En effet, chaque commande du
`Dockerfile` a pour but de modifier le système de fichiers.
Pour avoir le résultat escompté, il faut exécuter les commandes ensemble :
```
COPY db.sql /db.sql
RUN service mysqld start && mysql -u root -p toor virli < /db.sql
```
Après le `RUN`, MySQL sera de nouveau arrêté, si on veut l'utiliser dans le
conteneur, il ne faudra pas oublier de lancer le processus.
## Exposer des ports
Construisons maintenant un conteneur avec un serveur web :
```
FROM my_editor
RUN apt-get update
RUN apt-get install -y nginx
EXPOSE 80
```
L'instruction `EXPOSE` sera traité plus tard par le client Docker
(équivalent à l'argument `--expose`). Il s'agit de préciser les ports
sur lesquels votre image écoute.
En utilisant l'option `-P` du `run`, vous allez pouvoir assigner une
redirection de port aléatoire sur la machine hôte vers votre
conteneur :
```
docker build --tag=my_webserver .
docker run -it -P my_webserver /bin/bash
service nginx start
```
Dans un autre terminal, lancer un `docker ps` et consulter la colonne
*PORTS* pour connaître le port choisit par Docker pour effectuer la
redirection.
Rendez-vous ensuite dans votre navigateur sur <http://localhost:49153/>.
À vous de jouer : utilisez l'instruction `COPY` pour afficher votre
propre `index.html` remplaçant celui installé de base par nginx.
## Lancement de commande automatique
Vous pouvez placer dans un `Dockerfile` une instruction `CMD` qui sera
exécutée si aucune commande n'est passée lors du `run`, par exemple :
```
CMD nginx -g "daemon off;"
```
```
docker build --tag=my_nginx .
docker run -d -P my_nginx
```
L'option `-d` passée au `run` lance le conteneur en tâche de
fond. Si vous constatez via un `docker ps` que le conteneur s'arrête
directement, retirer cette option pour voir ce qui ne va pas, ou
utilisez la commande `docker logs`.
## D'autres instructions ?
2016-09-08 02:40:34 +00:00
Consultez <https://docs.docker.com/engine/reference/builder/> pour la liste complète
2015-10-22 03:25:20 +00:00
des instructions reconnues.
## Rendu
### Exercice
Rendez le fichier `Dockerfile` et son contexte (`index.html`, fichiers de conf
éventuels, ...) que vous avez utiliser pour réaliser votre image
`my_webserver`.
### Questions
1. De combien de couches de systèmes de fichiers est composé votre image
2017-06-25 18:40:22 +00:00
`my_webserver` ? Justifiez votre décompte. Comment pourriez-vous en avoir
moins ?
2015-10-22 03:25:20 +00:00
1. On a vu comment créer une nouvelle image à partir d'une image existante
2017-06-25 18:40:22 +00:00
(`FROM`). Mais comment sont créés ces images de bases (comme debian ou
ubuntu) ?
2015-10-22 03:25:20 +00:00
1. Quels sont les avantages de ce `RUN` :
```
RUN apt-get update && \
apt-get install -y \
nginx \
php5-fpm \
php5-mysql \
php5-gd \
&& apt-get clean && \
rm -rf /var/lib/apt/lists/* /tmp/* /var/tmp/*
```
par rapport aux précédents exemples :
```
RUN apt-get update
2017-06-25 18:40:22 +00:00
RUN apt-get install -y nginx php5-fpm php5-mysql php5-gd
2015-10-22 03:25:20 +00:00
```