---
title: Howto Docker
categories: docker
---

Docker est une solution qui permet de créer, déployer et gérer en toute
simplicité des conteneurs Linux.
Elle combine plusieurs technologies pour rendre l'utilisation
des conteneurs accessible à tous.

Documentation : <https://docs.docker.com/engine/installation/linux/docker-ce/debian/#install-docker-ce-1>

Docker-Compose : [HowtoDockerCompose]()

# Docker Engine

## Installation

~~~
# apt install apt-transport-https
# echo "deb http://download.docker.com/linux/debian stretch stable" > /etc/apt/sources.list.d/docker.list
# curl -fsSL https://download.docker.com/linux/debian/gpg | apt-key add -
# apt update
# apt install docker-ce
~~~

> *Note* : Pour Debian 8 :
>
> ~~~
> # echo "deb http://apt.dockerproject.org/repo debian-jessie main" > /etc/apt/sources.list.d/docker.list
> # apt-key adv --keyserver hkp://p80.pool.sks-keyservers.net:80 --recv-keys 58118E89F3A912897C070ADBF76221572C52609D
> # apt update
> # apt install docker-engine
> # adduser <USER> docker
> ~~~

### Configuration

#### Changer le chemin de stockage

Créer le fichier `/etc/docker/daemon.conf` et y mettre :

~~~
{
    "graph": "<VOTRE_CHEMIN>",
    "storage-driver": "overlay"
}
~~~

### Ansible

Le rôle docker-host permet d'installer le docker-engine sur un hôte distant et
de l'exposer à l'externe ou non.

La documentation concernant l'utilisation du rôle est située dans son répertoire.

#### TLS

Lorsque le docker-engine est exposé, il est important de le sécuriser avec TLS.

Au moment de l'installation, une version altérée de shellpki est copiée dans le
répertoire docker/tls. Ensuite, les certificats et la clé sont créés pour le
serveur. (`shellpki init`)

Pour autoriser des hôtes à se connecter à l'engine, il faut leur créer une clé
et un certificat.
Pour ce faire, il suffit de lancer le script:

~~~
/home/docker/tls$ ./shellpki create
~~~

Les fichiers seront créés, par défaut, dans le répertoire
`/home/docker/tls/files/$CN`

## Utilisation de base

Une image Docker contient un OS avec un ou plusieurs services préconfigurés.
Un conteneur quant à lui est une instance (créée à partir d'une image)
en cours d'execution.

### Lister les conteneurs et les images:

~~~
$ docker ps [options]
~~~

Voici quelques options utiles pour la commande `ps`

~~~
-a : Lister tous les conteneurs
-l : Lister les conteneurs récentralise
-q : Lister uniquement les ID des conteneurs
~~~

### Démarrer un conteneur

~~~
$ docker run [options] IMAGE [commande]
~~~

Options courantes:

~~~
--name="nom"                : Donner un nom au conteneur
-p port_hôte:port_conteneur : Rendre un port accessible depuis l'hôte
-d                          : Lancer le conteneur en mode 'détaché'
-it                         : Lancer le conteneur en mode intéractif avec tty
~~~

Pour plus d'options, consulter `$ man docker run`

###  Éteindre ou tuer un conteneur

~~~
$ docker stop|kill [options] CONTENEUR
~~~

CONTENEUR correspond au nom ou à l'ID du conteneur.

Lorsque le conteneur n'est plus en fonction, il existe toujours et peut être
lister à l'aide de la commande `$ docker ps -a`

### Supprimer un conteneur ou une image

~~~
$ docker rm [options] CONTENEUR
ou
$ docker rmi [options] IMAGE
~~~

### Exécuter des commandes au sein d'un conteneur en marche

~~~
$ docker exec [options] CONTENEUR COMMANDE
~~~

Options courante:

~~~
-it : Lancer la commande de manière intéractive dans un TTY.
~~~

### Visionner les logs d'un conteneur

~~~
$ docker logs [options] CONTENEUR
~~~

Option:

~~~
-f : Suivre les logs en direct
~~~

### Se connecter à un conteneur en marche

S'il est nécessaire d'intéragir directement avec un process lancé dans un
conteneur, il faut utiliser la commande `attach`.
Dans le cas où l'on souhaite simplement visionner la sortie (logs) du conteneur,
il faut utiliser `logs`.
Pour lancer un terminal ou une commande supplémmentaire, utiliser `exec`.

~~~
docker attach [options] CONTENEUR
~~~

**ATTENTION!!!**

Lorsque le conteneur est attaché, l'utilisation de *CTRL+C* termine le processus
en cours. La commande *CTRL+P+Q* doit être utilisé ou l'on doit ajouter l'option
`--sig-proxy=false` lors du lancement ou de l'attachement.


### Astuces
Éteindre/Tuer/Supprimer tous les conteneurs:

~~~
$ docker stop|kill|rm $(docker ps -aq)
~~~

Supprimer toutes les images:

~~~
$ docker rmi $(docker images -q)
~~~

Lancer un terminal bash dans un conteneur en marche:

~~~
$ docker exec -it CONTENEUR bash
~~~

Démarrer un conteneur avec un terminal bash:

~~~
$ docker run -it IMAGE bash
~~~

### Dépannage

#### Problème de connectivité à l'intérieur des conteneurs
Solution:

Redémarrer le service docker

#### Espace insuffisant lors d'un build
Solutions:

- Vérifier que le "build context" n'est pas trop grand.
- Modifier la variable d'environnement  DOCKER_TMPDIR .
- Créer un fichier .dockerignore pour exclure des fichiers et répertoires
  du "build context"

*Build context: Tout ce qui se trouve à la racine du Dockerfile.*

## Dockerfile

Exemple :

~~~
FROM debian:stretch
MAINTAINER John Doe <jdoe@example.com>

ENV DEBIAN_FRONTEND noninteractive

RUN (apt-get update && apt-get upgrade -y -q && apt-get dist-upgrade -y -q && apt-get -y -q autoclean && apt-get -y -q autoremove)
RUN apt-get install -y -q mariadb-server

EXPOSE 3306
CMD ["mysqld"]
~~~

~~~
# ls
Dockerfile

# docker build -t mariadb .

# docker images
REPOSITORY          TAG                 IMAGE ID            CREATED             SIZE
mariadb             latest              4bea99cda08c        8 minutes ago       470MB
debian              stretch             5b712ae16dd7        3 days ago          100MB
~~~

## Utilisation avancée

### Swarm

Swarm permet de mettre en communication plusieurs hôtes Docker afin d'en former
un cluster. On pourra ainsi déployer des applications multi-conteneurs sur
plusieurs machines.

Initialiser le cluster :

~~~
docker0# docker swarm init
~~~

Joindre les autres machines au cluster créé (il vous suffit généralement de copier-coller la commande retournée par `docker swarm init` :

~~~
docker1# docker swarm join --token <token> <IP du premier node>
~~~

Par défaut la machine sur laquelle le cluster a été initialisée a le rôle de
_manager_, et les suivantes ont le rôle de _worker_. On ne peut déployer de
nouveaux services que depuis les _managers_. Les _workers_ se contentent de
recevoir les services à rouler.

Pour ajouter des machines plus tard, il suffit de générer un nouveau token :

~~~
docker0# docker swarm join-token <manager|worker>
~~~

### Compose/stack

Docker permet de déployer des infrastructures multi-conteneurs (_stacks_) simplement à l'aide de `docker stack` (anciennement Docker Compose, logiciel tier). Il est très utile dans le cadre de déploiement sur un cluster Swarm.

L'infra est à décrire dans un fichier YAML.

Déployer (ou mettre à jour à chaud) une nouvelle _stack_ :

~~~
# docker stack deploy -c <stack_name.yml> <stack name>
~~~

Lister les _stacks_ :

~~~
# docker stack ls
~~~

Lister les _services_, toutes _stacks_ confondues ou pour une _stack_ donnée :

~~~
# docker service ls
# docker stack services <stack name>
~~~

Lister les _tasks_ (replicas) d'une _stack_ ou d'un _service donnée :

~~~
# docker stack ps <stack name>
# docker service ps <service name>
~~~

Supprimer une _stack_ :

~~~
# docker stack rm <stack name>
~~~

### Réseaux

Docker permet de gérer différentes topologies de réseaux pour connecter les conteneurs entre eux à l'aide de `docker network`.

_drivers_ réseau supportés :

  - _bridge_ : utilise les bridges Linux ;
  - _overlay_ : utilisé dans le cas d'un cluster Swarm, permet d'avoir un
    réseau unique partagé entre tous les hôtes Docker et permet de faire du
    load-balancing entre les conteneurs (replicas) d'un service ;
  - _macvlan_ : permet d'assigner directement des adresses IP publiques aux
    conteneurs, donc aucun NAT n'est fait contrairement aux précédents.

Créer un réseau :

~~~
# docker create -d <driver> […] <network name>
~~~

Lister les réseaux créés :

~~~
# docker network ls
~~~

Informations détaillées sur un réseau :

~~~
# docker network inspect <network name>
~~~
