# Docker from Zero to GigaChad Docker ça faire presque tous ce qu'on veut avec conteneurs. ## Écrire un Dockerfile Un Dockerfile c'est une _recette_ pour construire une image Docker et ça ressemble à ça: ```Dockerfile FROM python:3.8 COPY requirements.txt . RUN pip install -r requirements.txt COPY main.py main.py ENTRYPOINT ["python", "main.py"] ``` On reconnait **3** parties essentielles: ### L'image de base ```Dockerfile FROM python:3.8 ``` C'est une image de laquelle on s'inspire pour créer la notre, ça nous évite d'avoir à installer python nous même par exemple. ### Un ensemble d'instructions ```Dockerfile COPY requirements.txt . RUN pip install -r requirements.txt COPY main.py main.py ``` Ces instructions s'exécutent lors de la construction de l'image. Les instructions les plus courantes sont: Pour ajouter des fichiers dans l'image: ```Dockerfile COPY <un fichier/dossier sur mon pc> <un emplacement dans mon image> COPY --chown=user:group <mon fichier> <ma destination> ``` Pour lancer une commande dans l'image: ```Dockerfile RUN ma commande ``` ### Un entrypoint C'est la commande qui s'exécutent lorsque le conteneur est démarre à partir de l'image. Deux façons possible de l'écrire: exec form: ```Dockerfile ENTRYPOINT ["mon executable", "arg1", "arg2"] ``` C'est la façon préférée de faire. shell form: ```Dockerfile ENTRYPOINT ma commande 1 && ma commande 2 ``` nécessaire lorsque l'on a plusieurs commande à faire tourner de façon séquentielle. ### Le multi-stage build Parfois on a pas besoin d'une image différent pour pouvoir build l'application et pour distribuer cette application. On utilise alors un multi-stage build. Voilà un petit exemple. ```Dockerfile FROM golang:1.16 WORKDIR /go/src/github.com/alexellis/href-counter/ RUN go get -d -v golang.org/x/net/html COPY app.go ./ RUN CGO_ENABLED=0 GOOS=linux go build -a -installsuffix cgo -o app . FROM alpine:latest RUN apk --no-cache add ca-certificates WORKDIR /root/ COPY --from=0 /go/src/github.com/alexellis/href-counter/app ./ CMD ["./app"] ``` Seul le dernier stage est conservé dans l'image construite. ## Construire une image à partir d'un Dockerfile Une image se construit à partir d'un Dockerfile et d'un contexte (c'est un dossier qui correspond au **.** que tu as mis dans to Dockerfile). Souvent le contexte c'est `.` et il n'y a pas besoin de spécifier l'emplacement du Dockerfile, si il s'appelle `Dockefile` et est à la racine du contexte. Pour constuire l'image on utilise alors: ```bash docker build . -t <le nom de mon image>:<tag> ``` Le tag sert à spécifier plusieurs version de la même image, un peu comme des branches sur git. ## Push une image sur un registry Un registry c'est juste un espace de stockage disponible pour héberger des images Docker. ```bash # On se log au registry (les identifiants sont sur le bitwarden) docker login registry.viarezo.fr # On build l'image avec le nom du registry dedans docker build . -t registry.viarezo.fr/<nom du projet>/<image>:<tag> # On push l'image sur le registry docker push registry.viarezo.fr/<nom du projet>/<image>:<tag> ``` Attention il faut avoir créé le projet au préalable sur le registry, en cochant bien l'option public. ## Faire tourner un conteneur à partir d'une image Une fois qu'on a construit notre image, on peut l'utiliser pour créer autant de conteneurs que l'on veut: ```bash docker run <image> # En forwardant un port docker run -p <port sur mon pc>:<port dans le conteneur> <image> # En ajoutant des variables d'environnement docker run -e FOO=BAR <image> # Avec un .env docker run --env-file .env <image> ``` ## Gérer les conteneurs qui s'exécutent ```bash # Voir les conteneurs qui tournent et les informations associées docker ps # Stopper un conteneur docker stop <conteneur> # Redémarrer un conteneur stoppé docker start <conteneur> # Supprimer un conteneur stoppé docker rm <conteneur> ``` ## Débugger un conteneur ```bash # Voir les logs docker logs <conteneur> # Executer une commande dans un conteneur docker exec -it <conteneur> <commande> # Récupérer un shell dans un conteneur (attention bash ne marche pas pour les images alpine) docker exec -it <conteneur> sh/bash ```