Développement Containerisé avec Docker, VSCode et GitLab CI : Un Guide Pratique
Boostez votre productivité en développement avec une configuration optimisée pour Go, Java, Angular, Nginx et C++ basée sur des images Red Hat

- Développement Containerisé avec Docker, VSCode et GitLab CI : Un Guide Pratique
- Développement Containerisé avec Docker, VSCode et GitLab CI : Un Guide Pratique
- Introduction
- Configuration de VSCode pour le Développement en Conteneurs
- Étape 1 : Installer les extensions essentielles
- Étape 2 : Configurer le débogage de conteneurs
- Dockerfiles Multi-étages Optimisés
- Configuration GitLab CI/CD
- Optimisation des Images Docker
- 1. Compression des Instructions RUN
- 2. Utilisation de Volumes pour les Caches
- 3. Nettoyage des Caches après Installation
- Gestion des Versions
- Alternative: Utilisation d’Images Alpine
- Les Images Alpine: Ultra-légères mais avec des compromis
- Maven + Jenkins avec Alpine: Un exemple concret
- Configuration de Jenkins pour les Images Alpine
- Avantages et Risques des Images Alpine
- ✅ Avantages:
- ⚠️ Risques et Inconvénients:
- Quand choisir Red Hat UBI vs Alpine?
- Conclusion
- Comparaison des Architectures CI/CD: GitLab CI vs Jenkins
- Exemple équivalent avec Jenkins pour une application Maven
- Ressources Supplémentaires
Introduction
La containerisation a révolutionné le développement logiciel moderne. Dans ce tutoriel, nous vous montrons comment configurer un environnement de développement puissant et cohérent en utilisant Docker, Visual Studio Code et GitLab CI. Notre approche fonctionne pour plusieurs langages de programmation populaires et optimise à la fois le développement local et l’intégration continue.
Qu’allez-vous apprendre ?
- Configuration de VSCode pour le développement en conteneurs
- Création de Dockerfiles multi-étapes optimisés
- Mise en place d’un pipeline CI/CD avec GitLab
- Optimisation des performances et de la taille des images
- Stratégies de gestion de versions
Prêt à améliorer considérablement votre flux de travail ? C’est parti !
Configuration de VSCode pour le Développement en Conteneurs
Étape 1 : Installer les extensions essentielles
Pour commencer, installez ces extensions dans VSCode :
- Remote – Containers
- Docker
- GitLab Workflow
- Extensions spécifiques aux langages (Go, Java, Angular, C++)
Étape 2 : Configurer le débogage de conteneurs
Créez un fichier .vscode/launch.json
avec cette configuration :
{
"configurations": [
{
"name": "Go: Docker Debug",
"type": "docker",
"request": "launch",
"preLaunchTask": "docker-run: debug-go",
"platform": "go",
"go": {
"remoteRoot": "/app"
}
},
{
"name": "Angular: Docker Debug",
"type": "docker",
"request": "launch",
"preLaunchTask": "docker-run: debug-angular",
"platform": "node",
"node": {
"remoteRoot": "/app"
}
}
]
}
Cette configuration permettra de déboguer directement dans les conteneurs, en gardant toutes les fonctionnalités habituelles comme les points d’arrêt et l’inspection des variables.
Dockerfiles Multi-étages Optimisés
Un des secrets pour des conteneurs efficaces est l’utilisation de builds multi-étages. Voici un exemple pour une application Go :
# Base pour le développement et la compilation
FROM registry.access.redhat.com/ubi8/go-toolset:1.19 AS base
# Étape de développement
FROM base AS dev
WORKDIR /app
RUN go install github.com/go-delve/delve/cmd/dlv@latest
ENV GO111MODULE=on
CMD ["tail", "-f", "/dev/null"]
# Étape de compilation
FROM base AS build
WORKDIR /app
COPY go.* ./
RUN go mod download
COPY . .
RUN go build -o app .
# Image finale minimale
FROM registry.access.redhat.com/ubi8/ubi-minimal:8.7
WORKDIR /app
COPY --from=build /app/app .
USER 1001
ENTRYPOINT ["./app"]
Astuce Pro : Cette approche multi-étages sépare l’environnement de développement de l’image de production, permettant d’avoir une image finale beaucoup plus légère !
Configuration GitLab CI/CD
GitLab CI/CD permet d’automatiser vos tests et déploiements. Voici comment configurer un pipeline de base :
stages:
- validate
- build
- test
- deploy
variables:
DOCKER_DRIVER: overlay2
CI_REGISTRY: "registry.example.com"
# Job de validation pour Go
go-lint:
stage: validate
image: registry.access.redhat.com/ubi8/go-toolset:1.19
script:
- go install github.com/golangci/golangci-lint/cmd/golangci-lint@latest
- golangci-lint run ./...
# Job de build pour Angular
angular-build:
stage: build
image: registry.access.redhat.com/ubi8/nodejs-18:1-70
script:
- npm ci
- npm run build -- --configuration production
artifacts:
paths:
- dist/
Ce fichier .gitlab-ci.yml
définit un pipeline simple avec des étapes de validation, build, test et déploiement.
Optimisation des Images Docker
La taille des images affecte directement les performances de votre pipeline. Voici quelques techniques d’optimisation essentielles :
1. Compression des Instructions RUN
# Avant - Multiple couches
RUN apt-get update
RUN apt-get install -y curl
RUN apt-get install -y nginx
# Après - Une seule couche avec nettoyage
RUN apt-get update && \
apt-get install -y --no-install-recommends curl nginx && \
apt-get clean && \
rm -rf /var/lib/apt/lists/*
2. Utilisation de Volumes pour les Caches
Pour optimiser le développement local, utilisez des volumes pour préserver les caches :
services:
go-dev:
volumes:
- .:/app
- go-cache:/go/pkg/mod
environment:
- GOCACHE=/go/cache
volumes:
go-cache:
driver: local
3. Nettoyage des Caches après Installation
# Nettoyage après installation npm
RUN npm ci && npm cache clean --force
Gestion des Versions
La gestion des versions est critique pour maintenir votre code organisé. Adoptez le versionnement sémantique (SemVer) :
- Version MAJEURE (X.y.z) : changements incompatibles
- Version MINEURE (x.Y.z) : nouvelles fonctionnalités compatibles
- Version CORRECTIF (x.y.Z) : corrections de bugs
Automatisez vos montées de version avec un script simple :
#!/bin/bash
# bump-version.sh
TYPE=$1 # major, minor, or patch
VERSION_FILE="VERSION"
CURRENT_VERSION=$(cat $VERSION_FILE)
# Split version
MAJOR=$(echo $CURRENT_VERSION | cut -d. -f1)
MINOR=$(echo $CURRENT_VERSION | cut -d. -f2)
PATCH=$(echo $CURRENT_VERSION | cut -d. -f3)
# Bump selon le type
case $TYPE in
major)
MAJOR=$((MAJOR + 1))
MINOR=0
PATCH=0
;;
minor)
MINOR=$((MINOR + 1))
PATCH=0
;;
patch)
PATCH=$((PATCH + 1))
;;
esac
NEW_VERSION="$MAJOR.$MINOR.$PATCH"
echo $NEW_VERSION > $VERSION_FILE
Intégrez ce script dans votre pipeline GitLab CI pour des montées de version automatisées.
Conclusion
Vous disposez maintenant d’une configuration professionnelle pour le développement containerisé avec VSCode et GitLab CI. Cette approche :
- Standardise les environnements de développement
- Accélère l’intégration de nouveaux développeurs
- Optimise les performances de build
- Réduit considérablement la taille des images
- Automatise le processus de livraison
Ne sous-estimez pas l’impact de ces optimisations – un pipeline bien configuré peut réduire drastiquement le temps de développement et améliorer la qualité de votre code.
Ressources Supplémentaires
- Documentation officielle Docker
- Guide des extensions Remote Development pour VSCode
- Documentation GitLab CI/CD
Vous avez aimé ce tutoriel ? Partagez-le avec vos collègues développeurs et laissez un commentaire ci-dessous si vous avez des questions !
[Mots-clés: Docker, VSCode, GitLab CI, DevOps, Développement, Conteneurs, CI/CD, Red Hat]
Développement Containerisé avec Docker, VSCode et GitLab CI : Un Guide Pratique
Boostez votre productivité en développement avec une configuration optimisée pour Go, Java, Angular, Nginx et C++ basée sur des images Red Hat

Introduction
La containerisation a révolutionné le développement logiciel moderne. Dans ce tutoriel, nous vous montrons comment configurer un environnement de développement puissant et cohérent en utilisant Docker, Visual Studio Code et GitLab CI. Notre approche fonctionne pour plusieurs langages de programmation populaires et optimise à la fois le développement local et l’intégration continue.
Qu’allez-vous apprendre ?
- Configuration de VSCode pour le développement en conteneurs
- Création de Dockerfiles multi-étapes optimisés
- Mise en place d’un pipeline CI/CD avec GitLab
- Optimisation des performances et de la taille des images
- Stratégies de gestion de versions
Prêt à améliorer considérablement votre flux de travail ? C’est parti !
Configuration de VSCode pour le Développement en Conteneurs
Étape 1 : Installer les extensions essentielles
Pour commencer, installez ces extensions dans VSCode :
- Remote – Containers
- Docker
- GitLab Workflow
- Extensions spécifiques aux langages (Go, Java, Angular, C++)
Étape 2 : Configurer le débogage de conteneurs
Créez un fichier .vscode/launch.json
avec cette configuration :
{
"configurations": [
{
"name": "Go: Docker Debug",
"type": "docker",
"request": "launch",
"preLaunchTask": "docker-run: debug-go",
"platform": "go",
"go": {
"remoteRoot": "/app"
}
},
{
"name": "Angular: Docker Debug",
"type": "docker",
"request": "launch",
"preLaunchTask": "docker-run: debug-angular",
"platform": "node",
"node": {
"remoteRoot": "/app"
}
}
]
}
Cette configuration permettra de déboguer directement dans les conteneurs, en gardant toutes les fonctionnalités habituelles comme les points d’arrêt et l’inspection des variables.
Dockerfiles Multi-étages Optimisés
Un des secrets pour des conteneurs efficaces est l’utilisation de builds multi-étages. Voici un exemple pour une application Go :
# Base pour le développement et la compilation
FROM registry.access.redhat.com/ubi8/go-toolset:1.19 AS base
# Étape de développement
FROM base AS dev
WORKDIR /app
RUN go install github.com/go-delve/delve/cmd/dlv@latest
ENV GO111MODULE=on
CMD ["tail", "-f", "/dev/null"]
# Étape de compilation
FROM base AS build
WORKDIR /app
COPY go.* ./
RUN go mod download
COPY . .
RUN go build -o app .
# Image finale minimale
FROM registry.access.redhat.com/ubi8/ubi-minimal:8.7
WORKDIR /app
COPY --from=build /app/app .
USER 1001
ENTRYPOINT ["./app"]
Astuce Pro : Cette approche multi-étages sépare l’environnement de développement de l’image de production, permettant d’avoir une image finale beaucoup plus légère !
Configuration GitLab CI/CD
GitLab CI/CD permet d’automatiser vos tests et déploiements. Voici comment configurer un pipeline de base :
stages:
- validate
- build
- test
- deploy
variables:
DOCKER_DRIVER: overlay2
CI_REGISTRY: "registry.example.com"
# Job de validation pour Go
go-lint:
stage: validate
image: registry.access.redhat.com/ubi8/go-toolset:1.19
script:
- go install github.com/golangci/golangci-lint/cmd/golangci-lint@latest
- golangci-lint run ./...
# Job de build pour Angular
angular-build:
stage: build
image: registry.access.redhat.com/ubi8/nodejs-18:1-70
script:
- npm ci
- npm run build -- --configuration production
artifacts:
paths:
- dist/
Ce fichier .gitlab-ci.yml
définit un pipeline simple avec des étapes de validation, build, test et déploiement.
Optimisation des Images Docker
La taille des images affecte directement les performances de votre pipeline. Voici quelques techniques d’optimisation essentielles :
1. Compression des Instructions RUN
# Avant - Multiple couches
RUN apt-get update
RUN apt-get install -y curl
RUN apt-get install -y nginx
# Après - Une seule couche avec nettoyage
RUN apt-get update && \
apt-get install -y --no-install-recommends curl nginx && \
apt-get clean && \
rm -rf /var/lib/apt/lists/*
2. Utilisation de Volumes pour les Caches
Pour optimiser le développement local, utilisez des volumes pour préserver les caches :
services:
go-dev:
volumes:
- .:/app
- go-cache:/go/pkg/mod
environment:
- GOCACHE=/go/cache
volumes:
go-cache:
driver: local
3. Nettoyage des Caches après Installation
# Nettoyage après installation npm
RUN npm ci && npm cache clean --force
Gestion des Versions
La gestion des versions est critique pour maintenir votre code organisé. Adoptez le versionnement sémantique (SemVer) :
- Version MAJEURE (X.y.z) : changements incompatibles
- Version MINEURE (x.Y.z) : nouvelles fonctionnalités compatibles
- Version CORRECTIF (x.y.Z) : corrections de bugs
Automatisez vos montées de version avec un script simple :
#!/bin/bash
# bump-version.sh
TYPE=$1 # major, minor, or patch
VERSION_FILE="VERSION"
CURRENT_VERSION=$(cat $VERSION_FILE)
# Split version
MAJOR=$(echo $CURRENT_VERSION | cut -d. -f1)
MINOR=$(echo $CURRENT_VERSION | cut -d. -f2)
PATCH=$(echo $CURRENT_VERSION | cut -d. -f3)
# Bump selon le type
case $TYPE in
major)
MAJOR=$((MAJOR + 1))
MINOR=0
PATCH=0
;;
minor)
MINOR=$((MINOR + 1))
PATCH=0
;;
patch)
PATCH=$((PATCH + 1))
;;
esac
NEW_VERSION="$MAJOR.$MINOR.$PATCH"
echo $NEW_VERSION > $VERSION_FILE
Intégrez ce script dans votre pipeline GitLab CI pour des montées de version automatisées.
Alternative: Utilisation d’Images Alpine
Bien que notre tutoriel se concentre sur les images Red Hat UBI, une alternative populaire est l’utilisation d’images basées sur Alpine Linux. Explorons cette option et comparons les avantages et inconvénients.
Les Images Alpine: Ultra-légères mais avec des compromis
Alpine Linux est une distribution minimaliste qui a gagné en popularité dans l’écosystème Docker pour sa taille extrêmement réduite.
Comparaison des tailles:
- Image de base Red Hat UBI Minimal: ~114 MB
- Image de base Alpine: ~5 MB
Cette différence significative peut avoir un impact majeur sur vos temps de build et coûts de stockage.
Maven + Jenkins avec Alpine: Un exemple concret
Voici un exemple de Dockerfile utilisant Alpine pour une application Java avec Maven, optimisé pour s’intégrer à Jenkins:
# Étape de build avec Alpine
FROM alpine:3.17 AS builder
# Installation de Maven et JDK
RUN apk add --no-cache openjdk11 maven
# Configuration Maven
WORKDIR /app
COPY pom.xml .
COPY src ./src
# Build avec Maven
RUN mvn package -DskipTests
# Image finale minimale
FROM alpine:3.17
# Installation du JRE uniquement
RUN apk add --no-cache openjdk11-jre
# Copie de l'artefact
WORKDIR /app
COPY --from=builder /app/target/*.jar app.jar
# Utilisateur non-root pour la sécurité
RUN addgroup -S appgroup && adduser -S appuser -G appgroup
USER appuser
CMD ["java", "-jar", "app.jar"]
Configuration de Jenkins pour les Images Alpine
Voici un exemple de Jenkinsfile
optimisé pour ce type d’image:
pipeline {
agent any
environment {
DOCKER_IMAGE = 'myapp:${BUILD_NUMBER}'
}
stages {
stage('Build') {
steps {
sh 'docker build -t ${DOCKER_IMAGE} .'
}
}
stage('Analyze Image') {
steps {
sh '''
echo "Image size analysis:"
docker images ${DOCKER_IMAGE} --format "{{.Size}}"
echo "Layer analysis:"
docker history ${DOCKER_IMAGE}
'''
}
}
stage('Test') {
steps {
sh 'docker run --rm ${DOCKER_IMAGE} java -version'
}
}
stage('Deploy') {
when {
branch 'main'
}
steps {
sh 'docker tag ${DOCKER_IMAGE} myapp:latest'
sh 'docker push myapp:latest'
}
}
}
}
Avantages et Risques des Images Alpine
✅ Avantages:
- Taille réduite: 10 à 20 fois plus petites que des images standards
- Temps de déploiement accélérés: Moins de données à transférer
- Surface d’attaque réduite: Moins de packages installés = moins de vulnérabilités potentielles
- Efficacité en CI/CD: Builds et déploiements plus rapides
⚠️ Risques et Inconvénients:
- Bibliothèque C différente: Alpine utilise musl libc au lieu de glibc, ce qui peut causer des incompatibilités
- Problèmes de dépendances natives: Certaines bibliothèques compilées peuvent ne pas fonctionner sans modification
- Support limité: Moins de packages disponibles comparé à UBI ou Debian
- Courbe d’apprentissage: Utilise apk au lieu de apt/yum/dnf pour la gestion des packages
Conseil pratique: Avant de migrer complètement vers Alpine, testez soigneusement vos applications, particulièrement celles avec des dépendances natives ou des exigences spécifiques à glibc. Considérez Alpine comme une option pour les applications simples où la taille de l’image est prioritaire.
Quand choisir Red Hat UBI vs Alpine?
Choisissez Red Hat UBI quand:
- Vous avez besoin d’un support commercial et de conformité d’entreprise
- Votre application a des dépendances complexes
- Vous travaillez dans un environnement où Red Hat est déjà standardisé
- La sécurité et la stabilité sont plus importantes que la taille d’image
Choisissez Alpine quand:
- La taille de l’image et la performance sont critiques
- Votre application a peu de dépendances natives
- Vous pouvez tester rigoureusement la compatibilité
- Vous travaillez dans un environnement de développement ou startup
Conclusion
Vous disposez maintenant d’une configuration professionnelle pour le développement containerisé avec VSCode et GitLab CI, avec des alternatives selon vos besoins spécifiques. Cette approche :
- Standardise les environnements de développement
- Accélère l’intégration de nouveaux développeurs
- Optimise les performances de build
- Réduit considérablement la taille des images
- Automatise le processus de livraison
Ne sous-estimez pas l’impact de ces optimisations – un pipeline bien configuré peut réduire drastiquement le temps de développement et améliorer la qualité de votre code.
Comparaison des Architectures CI/CD: GitLab CI vs Jenkins
Bien que nous nous soyons concentrés sur GitLab CI dans ce tutoriel, Jenkins reste une solution populaire pour l’intégration continue. Voici une brève comparaison pour vous aider à choisir:
Critère | GitLab CI | Jenkins |
---|---|---|
Configuration | YAML (.gitlab-ci.yml) | Jenkinsfile (Groovy) ou interface GUI |
Intégration au SCM | Native avec GitLab | Plugins pour divers SCM |
Déploiement | Plus simple pour les déploiements clouds | Plus flexible pour les environnements complexes |
Courbe d’apprentissage | Modérée | Abrupte |
Extensibilité | Via GitLab CI/CD API | Vaste écosystème de plugins |
Conteneurisation | Native | Via plugins Docker |
Exemple équivalent avec Jenkins pour une application Maven
Pour ceux qui préfèrent utiliser Jenkins, voici un exemple de Jenkinsfile
pour une application Java avec Maven:
pipeline {
agent {
docker {
image 'maven:3.8.6-openjdk-11-slim'
args '-v $HOME/.m2:/root/.m2'
}
}
stages {
stage('Validate') {
steps {
sh 'mvn validate'
}
}
stage('Compile') {
steps {
sh 'mvn compile'
}
}
stage('Test') {
steps {
sh 'mvn test'
}
post {
always {
junit '**/target/surefire-reports/TEST-*.xml'
}
}
}
stage('Package') {
steps {
sh 'mvn package -DskipTests'
archiveArtifacts artifacts: 'target/*.jar', fingerprint: true
}
}
stage('Build Image') {
steps {
script {
def customImage = docker.build("my-java-app:${env.BUILD_ID}")
customImage.push()
customImage.push('latest')
}
}
}
}
}
Cet exemple montre comment Jenkins peut exécuter une pipeline Maven dans un conteneur Docker, avec persistance du cache Maven et gestion des artefacts.
Ressources Supplémentaires
- Documentation officielle Docker
- Guide des extensions Remote Development pour VSCode
- Documentation GitLab CI/CD
- Alpine Linux pour les conteneurs Docker
- Documentation Jenkins Pipeline
- Red Hat Universal Base Images (UBI)
Vous avez aimé ce tutoriel ? Partagez-le avec vos collègues développeurs et laissez un commentaire ci-dessous si vous avez des questions ou des expériences avec ces différentes approches !
[Mots-clés: Docker, VSCode, GitLab CI, Jenkins, DevOps, Développement, Conteneurs, CI/CD, Red Hat, Alpine Linux, Maven]
En savoir plus sur Wet & sea & IA
Subscribe to get the latest posts sent to your email.