Création d'une image Docker
Commençons avec un programme simple
Pour illustrer ce chapitre, commençons par un programme en Go qui affiche un message de bienvenue, ainsi que quelques informations sur votre système.
Créez un nouveau dossier et ajoutez-y ces deux fichiers “go.mod” et “hello-devops.go” :
module hello-devops
go 1.22.0
package main
import (
"fmt"
"runtime"
)
func main() {
fmt.Println("Hello DevOps!")
fmt.Println("Go version:", runtime.Version())
fmt.Println("Architecture:", runtime.GOARCH)
fmt.Println("OS:", runtime.GOOS)
}
Pour vérifier que tout fonctionne correctement, vous pouvez compiler ces programmes sur votre machine. Si ce n’est pas encore fait, téléchargez l’environnement de développement Go et installez-le sur votre machine.
Tapez maintenant la commande suivante dans un terminal :
go run .
et vous devriez obtenir quelque chose qui ressemble à ça :
Hello DevOps!
Go version: go1.22.0
Architecture: amd64 (ou arm64)
OS: windows (ou linux, ou darwin)
Bravo! Vous avez écrit un programme en Go!
Containairisation du programme
Mais si vous n’aviez pas envie (ou si vous ne pouviez pas) installer l’environnement de développement Go, vous auriez aussi pu exécuter ce programme en passant par une image Docker. C’est ce que nous allons faire maintenant.
Créez un fichier “Dockerfile” dans le même dossier :
FROM golang:1.22 AS builder
WORKDIR /app
COPY go.mod hello-devops.go ./
RUN go build .
FROM alpine:3.19
WORKDIR /root/
COPY --from=builder /app/hello-devops /usr/local/bin/hello-devops
CMD ["/usr/local/bin/hello-devops"]
Attention
Dans le Dockerfile
ci-dessus, nous téléchargeons les images du “registry” DockerHub.
En principe, les images téléchargées depuis DockerHub sont sauvées dans un cache local
et on ne devrait pas avoir de problème avec la limite de
100 téléchargements
que nous impose Docker.
Notez que pour contourner cette limite, vous pouvez aussi utiliser d’autres “registry” comme le Public Elastic Container Registry d’Amazone.
construisez une image Docker :
docker build -t hello-devops .
et exécutez-la :
docker run --rm hello-devops
Vous obtenez quelque chose comme ça :
Hello DevOps!
Go version: go1.22.0
Architecture: arm64
OS: linux
l’architecture est la même que votre machine (amd64 ou arm64), mais l’OS est maintenant “linux”, car le container fonctionne bien dans un environnement Linux.
Utilisation du CI/CD
Jusqu’ici, nous avons fait toutes les opérations sur notre ordinateur personnel. Il est temps de passer au CI/CD et laisser les ordinateurs du cloud faire le travail.
Ajoutez le fichier “.gitlab-ci.yml” à votre dossier :
image: docker:25.0
services:
- docker:25.0-dind
variables:
IMAGE_TAG_SLUG: $CI_REGISTRY_IMAGE:$CI_COMMIT_REF_SLUG
IMAGE_TAG_LATEST: $CI_REGISTRY_IMAGE:latest
before_script:
- docker info
build:
stage: build
script:
- docker build -t $IMAGE_TAG_LATEST .
- docker tag $IMAGE_TAG_LATEST $IMAGE_TAG_SLUG
- docker login -u $CI_REGISTRY_USER -p $CI_REGISTRY_PASSWORD $CI_REGISTRY
- docker push $IMAGE_TAG_SLUG
- docker push $IMAGE_TAG_LATEST
Note
le service docker:25.0-dind
(dind = Docker-in-Docker) permet de faire
tourner du Docker dans du Docker.
Le Service Informatique recommande l’utilisation de Kaniko pour la création d’image Docker. Cependant, Kaniko n’est pas encore capable de faire des images multi-architectures et c’est pourquoi nous ne l’utilisons pas ici. La documentation fait mention d’un “manifest-tool” pour construire les images multi-architectures, mais je trouve que c’est un peu compliqué et je préfère la méthode que je vais vous montrer dans le chapitre suivant.
Avec ce fichier, vous indiquez à GitLab ce qu’il doit faire quand une nouvelle version est poussée (push) dans le dépôt.
Si ce n’est pas déjà fait, créez un dépôt dans le GitLab de l’école et mettez-y tous les fichiers que vous venez de créer.
Après avoir synchronisé votre dépôt (avec git push
), vous devriez voir une nouvelle
entrée dans la section “CI/CD” → “Pipelines” :
Vous devriez aussi avoir une entrée dans “Deploy” → “Container registry”.
Vous pouvez télécharger et exécuter cette image avec la commande :
docker run --rm registry.forge.hefr.ch/<NAMESPACE>/<REPOSITORY>
Info
Si votre projet est privé, vous devrez probablement vous authentifier avant de pouvoir utiliser l’image :
docker login registry.forge.hefr.ch
et vous devriez obtenir ceci :
Hello DevOps!
Go version: go1.22.0
Architecture: amd64
OS: linux
L’architecture sera toujours amd64 car le runner qui a compilé votre programme dans GitLab est une machine avec une architecture amd64 et si vous faites tourner cette image sur un Mac récent (avec une puce ARM), vous observerez le message suivant:
WARNING: The requested image's platform (linux/amd64) does not match
the detected host platform (linux/arm64/v8) and no specific platform
was requested