Docker et Go : le guide complet pour la conteneurisation des applications Golang
La conteneurisation est devenue la norme de facto pour le déploiement d'applications modernes. Le langage Go (Golang) est parfaitement adapté à l'environnement conteneurisé : ses fichiers binaires compilés ne nécessitent pas d'exécution et l'édition de liens statiques permet de créer des images Docker minimales. Dans cet article, nous allons détailler le processus de conteneurisation d'applications Go, de la rédaction du Dockerfile à l'optimisation de la taille de l'image finale.
Pourquoi Go et Docker sont un duo idéal
Go se compile en un seul fichier binaire statique qui ne dépend pas des bibliothèques système. Cela signifie que pour exécuter une application Go dans un conteneur, il n'est pas nécessaire d'installer Go Runtime, des interpréteurs ou des dépendances supplémentaires. En conséquence, vous obtenez :
- Taille d'image minimale — souvent moins de 10-15 Mo
- Démarrage rapide — en millisecondes, pas en secondes
- Sécurité élevée — moins de composants = moins de vulnérabilités
- Simplicité de déploiement — un seul fichier binaire au lieu de multiples scripts et bibliothèques
Voyons cela à l'aide d'un exemple simple de serveur HTTP en Go.
Étape 1 : Création de l'application Go
Pour commencer, écrivons une application web simple que nous allons conteneuriser. Créez un fichier main.go :
package main
import ( "fmt" "log" "net/http" "os")
func main() { port := os.Getenv("PORT") if port == "" { port = "8080" }
http.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) { fmt.Fprintf(w, "Bonjour depuis le conteneur Go! 🐳") })
log.Printf("Serveur démarré sur le port %s", port) log.Fatal(http.ListenAndServe(":"+port, nil))}Il s'agit d'un serveur HTTP minimal qui écoute sur le port défini par la variable d'environnement PORT (par défaut 8080).
Étape 2 : Construction multi-étapes (Multi-stage build)
Pour créer une image Docker minimale, on utilise la construction multi-étapes. La première étape est la compilation de l'application, la seconde est la création de l'image finale avec uniquement le fichier binaire. Créez un Dockerfile :
# Étape 1 : Construction de l'applicationFROM golang:1.22-alpine AS builder
WORKDIR /app
# Copier go.mod et go.sum pour la mise en cache des dépendancesCOPY go.mod go.sum ./RUN go mod download
# Copier le code sourceCOPY . .
# Compiler le fichier binaire statiqueRUN CGO_ENABLED=0 GOOS=linux go build -o /app/server .
# Étape 2 : Image finale minimaleFROM alpine:3.19
# Ajouter les certificats CA pour HTTPSRUN apk --no-cache add ca-certificates
WORKDIR /root/
# Copier le binaire depuis la première étapeCOPY --from=builder /app/server .
# Ouvrir le portEXPOSE 8080
# Lancer l'applicationCMD ["./server"]Notez les points clés suivants :
golang:1.22-alpine— image légère pour la constructionCGO_ENABLED=0— désactiver CGO pour l'édition de liens statiquealpine:3.19— image Linux minimale (~5 Mo)ca-certificates— nécessaires si l'application utilise HTTPS
Étape 3 : Construction et lancement du conteneur
Construisez l'image Docker et lancez le conteneur :
# Construction de l'imagedocker build -t go-hello:latest .
# Lancement du conteneurdocker run -d -p 8080:8080 --name go-app go-hello:latest
# Vérificationcurl http://localhost:8080# Sortie : Bonjour depuis le conteneur Go! 🐳Vérifiez la taille de l'image obtenue :
docker images go-hello# REPOSITORY TAG IMAGE ID CREATED SIZE# go-hello latest abc123def456 10 seconds ago 14.2 MBSeulement 14.2 Mo — c'est infinitésimal comparé aux images Node.js (centaines de Mo) ou Python (dizaines de Mo).