Deployer Go avec Docker : Un Tutoriel Approfondi
Pourquoi Deployer Go avec Docker ?
Deployer une application Go en utilisant Docker offre plusieurs avantages pratiques :
Isolation et Sécurité : Les conteneurs créés avec Docker offrent une isolation complète des environnements, minimisant les risques de conflits entre dépendances et évitant les problèmes liés aux configurations système.
Portabilité : Un conteneur Docker est portable et peut être exécuté sur n'importe quel système qui supporte Docker, sans importe la configuration du système hôte.
Facilité de Déploiement : Le déploiement d'applications avec Docker devient simple et standardisé grâce à des fichiers
Dockerfileet aux commandes Docker. Cela permet une mise en production rapide et répétable.Échelle et Performance : Les conteneurs Docker s'exécutent efficacement sur de nombreux serveurs, facilitant l'échelle automatique et la gestion des ressources systèmes.
Un cas d'usage concret serait le déploiement d'une API Go à haute disponibilité dans un environnement cloud. Avec Docker, on peut facilement créer des instances dédiées pour chaque instance de l'API, assurer leur mise à jour et maintenance sans impact sur les autres services.
Prerequis
Avant de commencer, vous aurez besoin des éléments suivants :
Langage Go : Vérifiez que Go est installé en exécutant la commande
go version. Si ce n'est pas le cas, installez-le à partir du site officiel golang.org.go version # Devrait afficher une version valide de GoDocker : Installez Docker sur votre système. Vous pouvez trouver les instructions d'installation sur le site officiel de Docker.
docker --version # Devrait afficher une version valide de Docker
Concepts fondamentaux
1. Fichiers Dockerfile
Un Dockerfile est un fichier texte qui contient des instructions pour construire une image Docker. Voici un exemple simple :
## 📄 Dockerfile
FROM golang:1.17 AS builder
WORKDIR /app
COPY go.mod go.sum ./
RUN go mod download
COPY . .
RUN CGO_ENABLED=0 GOOS=linux go build -o main .
FROM alpine:latest
WORKDIR /root/
COPY --from=builder /app/main .
CMD ["./main"]
FROM golang:1.17 AS builder: Spécifie l'image de base pour la phase de construction.WORKDIR /app: Définit le répertoire de travail.COPY go.mod go.sum ./: Copie les fichiersgo.modetgo.sumdans le conteneur.RUN go mod download: Télécharge les dépendances Go spécifiées dansgo.mod.COPY . .: Copie tous les fichiers du répertoire local vers le conteneur.RUN CGO_ENABLED=0 GOOS=linux go build -o main .: Compile l'application en mode non-cross-platform pour Linux.
2. Images Docker
Une image Docker est une seule lecture et exécution de toutes les instructions dans un fichier Dockerfile. Elle est utilisée pour créer des conteneurs.
docker build -t my-go-app .
Cette commande construit une image nommée my-go-app à partir du Dockerfile courant.
3. Conteneurs Docker
Un conteneur Docker est une instance en cours d'exécution d'une image Docker. Il utilise les ressources système de l'hôte mais s'exécute en isolation.
docker run -d --name my-go-container my-go-app
Cette commande lance un conteneur nommé my-go-container à partir de l'image my-go-app.
Mise en pratique : Projet fil rouge
Dans ce tutoriel, nous allons créer une application simple d'une API Go qui permet de gérer des tâches. Nous utiliserons Docker pour empaqueter et déployer cette application.
Étape 1 : Création du projet Go
Créez un nouveau répertoire pour votre projet :
mkdir todo-api
cd todo-api
Créer le fichier main.go :
// 📄 main.go
package main
import (
"encoding/json"
"fmt"
"net/http"
)
type Task struct {
ID int `json:"id"`
Title string `json:"title"`
Done bool `json:"done"`
}
var tasks = []Task{
{ID: 1, Title: "Buy groceries", Done: false},
{ID: 2, Title: "Read a book", Done: true},
}
func getTasks(w http.ResponseWriter, r *http.Request) {
w.Header().Set("Content-Type", "application/json")
json.NewEncoder(w).Encode(tasks)
}
func main() {
http.HandleFunc("/tasks", getTasks)
fmt.Println("Starting server at port 8080")
if err := http.ListenAndServe(":8080", nil); err != nil {
fmt.Println(err)
}
}
Étape 2 : Création du fichier Dockerfile
Créez un fichier Dockerfile à la racine de votre projet :
## 📄 Dockerfile
FROM golang:1.17 AS builder
WORKDIR /app
COPY go.mod go.sum ./
RUN go mod download
COPY . .
RUN CGO_ENABLED=0 GOOS=linux go build -o main .
FROM alpine:latest
WORKDIR /root/
COPY --from=builder /app/main .
CMD ["./main"]
Étape 3 : Construction de l'image Docker
Construisez l'image Docker en exécutant la commande suivante :
docker build -t todo-api .
Étape 4 : Lancement du conteneur
Lancez le conteneur avec la commande suivante :
docker run -d --name todo-app-container -p 8080:8080 todo-api
Étape 5 : Vérification de l'API
Accédez à http://localhost:8080/tasks dans votre navigateur ou en utilisant curl pour vérifier que l'API fonctionne correctement :
curl http://localhost:8080/tasks
Vous devriez voir la liste des tâches JSON.
Erreurs frequentes et debugging
1. Erreur de build : "package main not in GOROOT"
Cause : Le chemin du fichier main.go n'est pas correct dans le Dockerfile.
Correction :
## ❌ Mauvais
COPY . .
## ✅ Correct
COPY ./ .
2. Erreur de runtime : "executable file not found in $PATH"
Cause : Le fichier exécutable n'est pas copié correctement dans le conteneur.
Correction :
## ❌ Mauvais
COPY main .
## ✅ Correct
COPY ./main .
3. Erreur de démarrage : "listen tcp :0: listen: address already in use"
Cause : Le port est déjà utilisé par un autre processus.
Correction :
docker run -d --name todo-app-container -p 8081:8080 todo-api
Pour aller plus loin
1. Utiliser Docker Compose pour gérer des applications multi-conteneurs
Docker Compose permet de définir et exécuter plusieurs conteneurs en un seul fichier.
## 📄 docker-compose.yml
version: '3'
services:
app:
build: .
ports:
- "8080:8080"
Ensuite, utilisez la commande suivante pour démarrer votre application :
docker-compose up -d
2. Créer des images multistage
Les images multistage permettent de réduire la taille des images en utilisant différentes étapes de construction.
## 📄 Dockerfile
FROM golang:1.17 AS builder
WORKDIR /app
COPY go.mod go.sum ./
RUN go mod download
COPY . .
RUN CGO_ENABLED=0 GOOS=linux go build -o main .
FROM alpine:latest
WORKDIR /root/
COPY --from=builder /app/main .
CMD ["./main"]
3. Utiliser des volumes pour persister les données
Les volumes permettent de persister les données entre les sessions du conteneur.
docker run -d --name todo-app-container -v $(pwd)/data:/app/data -p 8080:8080 todo-api
Défi pratique
Créez une API Go qui permet de créer, lire, mettre à jour et supprimer des utilisateurs. Utilisez Docker pour empaqueter et déployer votre application.
En suivant ce tutoriel, vous devriez être en mesure de comprendre comment utiliser Docker pour déploiement d'applications Go. N'hésitez pas à explorer les ressources supplémentaires et à pratiquer régulièrement pour améliorer vos compétences en gestion des conteneurs avec Docker.