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.24.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.24.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.24 AS builder
WORKDIR /app
COPY go.mod hello-devops.go ./
RUN go build .
FROM alpine:3.21
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. Pour des téléchargements anonymes, Dockerhub
impose une limite de 10
téléchargements
par adresse IP et par heure! Si vous ploquez votre propre adresse
IP, vous ne pourrez plus télécharger d’images Docker depuis
DockerHub, mais les dégâts ne toucheront que votre propre adresse
IP. Par contre, si vous bloquez l’adresse IP des serveurs de
l’école, vous bloquerez tout le monde pendant une heure!
Pour s’adapter à la limite imposée par DockerHub, nous commençons par créer un compte sur DockerHub. Rendez-vous sur DockerHub et créez un compte. Si le site vous demande de choisir entre un compte Work ou Personal, choisissez Personal.
Dès que vous avez créé votre compte, vous pouvez vous authentifier avec la commande suivante:
docker login
Suivez les instructions et vous devriez voir un message du genre :
Login Succeeded
Losque vous êtes authentifié, vous avez droit à 40 téléchargements par heure (et par utilisateur).
Note
Une autre manière de contourner la limite imposée par Dockerhub consiste à simplement utiliser un autre “registry” comme le Public Elastic Container Registry d’Amazone.
Note
Les “runners” de l’école utilisent un cache pour les images Docker provenant de DockerHub, mais lorsque nous utilisons Docker à l’itérieur de Docker (DinD), le cache n’est pas utilisé
construisez maintenant 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.24.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 :
.gitlab-ci.yml | |
---|---|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 |
|
Note
le service docker:27.5-dind
(dind = Docker-in-Docker) permet de faire
tourner du Docker dans du Docker.
Le Service Informatique recommandait 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.
Afin d’utiliser votre compte DockerHub dans le CI/CD, vous devez encore obtenir un token pour DockerHub. Connectez-vous à votre compte sur DockerHub et cliquez sur votre login name en haut à droite, puis sur Account Settings
Dans la section Personal access tokens, créez un nouvel Access Token avec le scope “Read, Write, Delete”.
Note
Si vous souhaitez uniquement lire les images publiques, vous pouvez choisir le scope “Public Repo Read-only”, mais plus tard nous allons publier notre image dans DockerHub et pour cela, nous avons besoin du scope “Read, Write, Delete”. Je vous recommande donc de choisir ce scope dès le début, mais d’un point de vue de la sécurité, il est préférable de choisir le scope le plus bas possible.
A la ligne 12 du fichier .gitlab-ci.yml
, ci-dessus, les deux variables d’environnement $DOCKERHUB_USER
et $DOCKERHUB_TOKEN
.
doivent contenir le user name et l’Access Token que vous venez de créer. Définissez ces variables dans votre projet GitLab :
Allez dans
“Settings” → “CI/CD” → “Variables” et ajoutez ces deux variables. Pour plus de sécurité, protégez le contenu de ces
variables en cochant la case Masked and hidden. Notez que pour $DOCKERHUB_USER
, vous pouvez vous contenter de protéger cette variable
avec l’option Masked.
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.24.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