# Docker - Create Image

# Création d'une image Lamp from scratch

Table des matières:

  • Préparation des dossiers
  • Création d'une image docker de base
  • Procédure de mise à jours de l'image
  • Création d'un Dockerfile pour une image type LAMP
  • Procédure de sauvegarde des images, Dockerfile et volumes
  • Démarrage de l'architecture via docker compose

Disclaimer : Pas de sudo ici, je travail sur une debian de base et en root. C'est pas de la prod aprés tout 😄

# Préparation des dossiers

Je précise, je fais ce tuto sur une Debian 9.5 Stretch(stable donc).

Je choisi de creer un dosier DockerData a la racine de mon OS, parceque j'aime bien tout contrôler!

mkdir /DockerData  # Futur dossier de travail de docker
mkdir /DockerPrep # Dossier qui va servir de ''brouillon''

Ensuite, on indique a Docker ou vont se situer ses données.

# On coupe le service docker
service docker stop

# On va ensuite modifier le fichier
# ici on suit la procédure d'un Linux avec systemD
nano /lib/systemd/system/docker.service

Vous allez devoir modifier la ligne

ExecStart=/usr/bin/dockerd -H fd://

par

ExecStart=/usr/bin/dockerd -g /DockerData -H fd://

Ensuite?

# Recharger les demons de systemD
systemctl daemon-reload

# Puis on redémarre le service docker
service docker start

# J'ai deja eu le cas ou il fallut en plus faire un 
systemctl restart docker

Normalement à ce stade un "tree /DockerData" devrait vous lister les dossiers de Docker ce qui devrait ressembler a cela:

DockerData/
├── builder
│   └── fscache.db
├── buildkit
│   ├── cache.db
│   ├── content
│   │   └── ingest
│   ├── executor
│   ├── metadata.db
│   └── snapshots.db
├── containerd
│   └── daemon
│       ├── io.containerd.content.v1.content
│       │   └── ingest
│       ├── io.containerd.metadata.v1.bolt
│       │   └── meta.db
│       ├── io.containerd.runtime.v1.linux
│       ├── io.containerd.snapshotter.v1.aufs
│       │   └── snapshots
│       ├── io.containerd.snapshotter.v1.btrfs
│       ├── io.containerd.snapshotter.v1.native
│       │   └── snapshots
│       ├── io.containerd.snapshotter.v1.overlayfs
│       │   └── snapshots
│       └── tmpmounts
├── containers
├── image
│   └── overlay2
│       ├── distribution
│       ├── imagedb
│       │   ├── content
│       │   │   └── sha256
│       │   └── metadata
│       │       └── sha256
│       ├── layerdb
│       └── repositories.json
├── network
│   └── files
│       └── local-kv.db
├── overlay2
│   └── l
├── plugins
│   ├── storage
│   │   └── blobs
│   │       └── tmp
│   └── tmp
├── runtimes
├── swarm
├── tmp
├── trust
└── volumes
    └── metadata.db

Voilà!

# Création d'une image docker de base

Première étape, l'image de base. On a la possibilité de créer une image littéralement "from scratch". Utile pour faire tourner une simple appli. Dans notre cas on va viser le fonctionnement de soft plus complexe tel qu'un serveur web et une base de donnée. On choisi donc un OS et tout naturellement, du Debian... non mais quoi d'autre? franchement?!

C'est donc parti pour créer une image docker avec un système Debian de base et minimal. Pour cela, nous allons utiliser debootstrap!

# mettons nous dans notre dossier de travail
cd /DockerPrep

# on installe debootstrap
apt-get update && apt-get -y install debootstrap

# on lance debootstrap en choisissant la distrib(la mienne)
# puis le dossier d'arrivé. ça va prendre quelques minutes
debootstrap stretch debian_stretch

# cette version permet d'avoir une image de moins de 170M
# debootstrap --variant=minbase stretch stretch.minimal

# la commande suivante va archiver le dossier précédemment créé
# et importer l'archive directement dans docker sous le nom debian9:v1
tar -C debian_stretch -c . | docker import - debian9:v1

# verification que tout cela a fonctionné
docker images

#cela doit retourner quelque chose comme ceci
REPOSITORY   TAG   IMAGE ID       CREATED              SIZE
debian9      v1    f001821d9306   About a minute ago   258MB

Vous voici donc avec une image dans docker d'une debian (9.5 dans mon cas).

# Procédure de mise à jours de l'image

On a une image, c'est parfait! Mais cette image va avoir besoin d'évoluer régulièrement et c'est ce que l'on va voir ici.

# On va commencer par créer un container avec cette image 
# et s'y connecter. La commande suivante crée le container 
# nommé debian9v1 a partir de l'image debian9:v1 puis
# vous y connecte vous fournissant bash
docker run -it --name debian9v1 debian9:v1 /bin/bash

# normalement votre terminal affiche quelque chose comme
# root@9bbd34cd5fc9:/#  Cela signifie que vous vous 
# trouvez sur l'image docker et non plus votre machine. 
# Vérifions qu'elle est a jour.
apt-get update && apt-get -y upgrade

# Nous somme pour la première fois dans ce container, 
# profitons en pour nettoyer au maximum cette image.
# Lister les paquets puis rettirer ceux que vous souhaitez
dpkg-query -l

# je vous laisse faire le ménage a votre gré!

# Container a jour et nettoyé, on donc en faire une image!
# Pensez à sortir du container avec exit

#Listons nos containers
docker ps -as

# ce qui retourne quelque chose du genre
CONTAINER ID  IMAGE       COMMAND      CREATED         STATUS   PORTS   NAMES
9bbd34cd5fc9  debian9:v1  "/bin/bash"  27 minutes ago  Exited           debian9v1

# Nous allons faire un commit ce qui va transformer ce
# container en image
docker commit 9bbd34cd5fc9 debian9:v2

# mais le commit a un désavantage, c'est qu'il prend de la place!
# En effet, le commit est comme une save, il garde les layers
# On peut lister les layer d'une image
docker history  debian9:v2

#ce qui retourne quelque chose du genre
IMAGE          CREATED         CREATED BY    SIZE      COMMENT
282564610f78   43 minutes ago  /bin/bash     79.7MB
f001821d9306   2 hours ago                   258MB     Imported from -

# Du coup, l'image occupe 258 + 80 = 338MB
# Il est possible de réduire cette taill en perdant l'historique
# apporter par les layers. Pour ça on exporte le container plutot
# que de le commit, puis on le réimporte en tant qu'image.
docker export id_du_container | docker import - debian9:v3

# et paf avec ça mon image tombe a 235MB !

Nous voilà avec une image à jour et avec une taille optimisé (ou à peu prés).

# Création d'un Dockerfile pour une image type LAMP

On retourne dans notre dossier de préparation et on creer un dossier lamp

cd /DockerPrep
mkdir lamp
cd lamp

#creation du Dockerfile
vi Dockerfile

Et maintenant bâtissons notre dockerfile

# On choisi notre image qui servira de base
FROM debian9:v1

# Quelques informations
LABEL description="Premier essai LAMP"
LABEL version="1.0"
MAINTAINER Draak (pouet@draak.fr)

# Copie de fichier
COPY start.sh /start.sh
RUN ["/bin/bash", "-c", "chmod +x /start.sh"]

# On installe les Paquets nécéssaire à savoir:
RUN /bin/bash -c "apt-get update && apt-get -y install apache2 mysql-server mysql-client php php-mysql"

# On execute le script de démarage

On n'oublie pas de faire le script de démarrage

#!/bin/sh
# Script Start du Docker
service enable apache2
service enable mysql 
service apache2 start
service mysql start

# Read sert a empecher le script de se fermer et a maintenir le docker ouvert
read a

Notre Dockerfile étant prêt, maintenant on va lancer la création de notre image Lamp.

docker build -t lamp-v1 .

# on vérifie ce qui la compose
docker history lamp-v1:latest

# On lance un container de cette image 
docker run -p 80:80 --name lamp-cont -t lamp-v1:latest

# Si on souhaite rentrer dans le dit container
docker exec -it lamp-cont /bin/bash

Et voila, On a une image faite de zero et qui tourne!