Déployer l’application sur une VM avec Docker Compose (CD)
Description générale
Passer de la CI à la CD en orchestrant le déploiement automatisé de l’application Flask + Redis sur une machine virtuelle via un job spécifique dans GitLab CI.
Déploiement automatisé de l’application avec Docker Compose
Description générale
L’objectif est d’automatiser la mise à jour du Docker Compose sur un serveur cible. On utilisera un script bash qui clone ou met à jour le dépôt, puis relance Docker Compose si le fichier est modifié.
Etape 0 : Ajouter le docker compose au dépôt
Attention : pensez à mettre le registry de Gitlab dans l'image du service.
Etape 1 : Créer un lien entre le serveur cible et GitLab
- Action : Générer un Deploy Token dans GitLab pour permettre l’accès au dépôt via
Settings > Repository > Deploy tokens
- Observation : Le mot de passe pour authentifier les actions Git est affiché et on peut faire un git pull depuis le serveur avec
git clone https://USER:PASS@gitlab.company.com/GROUP/PROJECT
- Contraintes :
- Nom du token : "gitlab+deploy-token"
- Date d'expiration :
sans
- Scopes :
read_repository
+read_repository
Etape 2 : Créer un script sur le serveur qui clone ou pull le code
- Action : Sur la VM (ou serveur cible), écrire un script bash qui :
- Vérifie si le répertoire du projet existe.
- Fait un
git clone
s’il est absent, ou ungit pull
s’il est présent.
- Observation : Le script doit utiliser le Deploy Token pour s’authentifier.
- Contraintes :
- Le dossier est
/home/stagiaire/myproject
- Le script est
deploy.sh
- Stocker l’utilisateur et le mot de passe du Deploy Token dans un fichier d'environnement
.env
- Utiliser la commande git ex:
git clone https://USER:PASS@gitlab.company.com/GROUP/PROJECT
- Le dossier est
Etape 3 : Redémarrer Docker Compose si le fichier a changé
- Action : Dans le même script, comparer si le
docker-compose.yml
a été modifié après un pull. - Observation : Relancer Docker Compose uniquement si des changements sont détectés.
- Contraintes :
- Utiliser
git show --pretty="" --name-only | grep 'docker-compose.yml'
pour détecter un changement récent du fichier - Utiliser
docker-compose pull
pour télécharger les nouvelles images d'abord. - Utiliser
docker-compose up -d --remove-orphans
pour recharger les services.
- Utiliser
Etape 4 : Créer une clé SSH sur le serveur
- Action : Gérer une clé SSH pour permettre au pipeline GitLab d’exécuter le script à distance.
Utilisezssh-keygen -t ecdsa
- Observation : La clé privée et la clé publique sont crées
- Contraintes :
- Générer la clé sans mot de passe
- Ajoutez le contenu de la clef publique dans le fichier
/home/stagiaire/.ssh/authorized_keys
Etape 5 : Créer une variable GitLab pour la clé privée
- Action : Ajouter la clé privée au projet GitLab (
Settings > CI/CD > Variables
). - Observation : La clef apparaît dans la liste des variables du projet
- Contraintes :
- Nom de la variable :
GITLAB_SSH_KEY
- Protéger cette variable pour éviter qu’elle ne soit exposée dans les forks ou branches non protégées.
- Nom de la variable :
Etape 6 : Modifier le fichier de CI pour faire de la CD
- Action : Créer dans
.gitlab-ci.yml
un nouveau stage pour le déploiement et un job nommé qui l'utilise. - Observation : Le job est lancé après le build Docker et les tests
- Contraintes :
- Nom du stage :
deploy
- Position du stage : après les autres
- Nom du job :
compose
- Image docker :
alpine:latest
- Le job “deploy” ne s’exécute que sur la branche principale (ex.
only: [main]
). - Script :
apk add --no-cache openssh-client"
- Nom du stage :
Etape 7 : Appeler le script bash de mise à jour en SSH
- Action : Ajouter au job une clef SSH locale et exécuter une commande
ssh
pour lancer le script d’update sur le serveur. - Observation : Le script va cloner/pull puis relancer Docker Compose si nécessaire.
- Contraintes :
- Créer des variables CICD:
SSH_USER
: formateurSSH_SERVER
: ip du serveur
- Créer un fichier
/tmp/id_ecdsa
qui contient la clef privée de la variable$GITLAB_SSH_KEY
- Changer les droits du fichier avec
chmod 600
- Utiliser les options suivantes pour ssh :
-o StrictHostKeyChecking=no
pour ne pas vérifier l’empreinte du serveur-i /tmp/id_ecdsa
pour utiliser la clef privée
- Appeler le script distant
/home/stagiaire/myproject/deploy.sh
avec la commande ssh utilisant les variables, et les diverses options.
- Créer des variables CICD:
Solution
Afficher
Exemple de script bash sur le serveur (deploy.sh)
#!/usr/bin/env bash
# source .env
PROJECT_DIR="/home/stagiaire/myproject"
DEPLOY_USER="gitlab+deploy-token-12345"
DEPLOY_PASS="super-secret-password"
GIT_REPO="https://${DEPLOY_USER}:${DEPLOY_PASS}@gitlab.com/mygroup/myproject.git"
if [ ! -d "$PROJECT_DIR" ]; then
git clone "$GIT_REPO" "$PROJECT_DIR"
cd "$PROJECT_DIR"
else
cd "$PROJECT_DIR"
git pull
fi
# Vérifier si docker-compose.yml a changé
CHANGED=$(git diff HEAD@{1} HEAD --name-only | grep 'docker-compose.yml' || true)
if [ "$CHANGED" != "" ]; then
docker-compose up -d --remove-orphans
fi
#! /usr/bin/env bash
source .env
PROJECT_DIR="/home/stagiaire/myproject"
DEPLOY_USER="gitlab+deploy-token-12345"
DEPLOY_PASS="super-secret-password"
PROJECT_GROUPE="uptimeformation"
PROJECT_NAME="testci"
GIT_REPO="https://${DEPLOY_USER}:${DEPLOY_PASS}@gitlab.company.com/$PROJECT_GROUPE/$PROJECT_NAME.git"
if [ ! -d "$PROJECT_DIR/$PROJECT_NAME" ]; then
cd "$PROJECT_DIR"
git clone "$GIT_REPO" "$PROJECT_NAME"
cd "$PROJECT_DIR/$PROJECT_NAME"
else
cd "$PROJECT_DIR/$PROJECT_NAME"
git pull
fi
# Vérifier si docker-compose.yml a changé
CHANGED=$(git show --pretty="" --name-only | grep 'docker-compose.yml' || true)
if [ "$CHANGED" != "" ]; then
docker-compose pull
docker-compose up -d --remove-orphans
fi
Exemple .gitlab-ci.yml
stages:
- build
- test
- deploy
...
compose:
stage: deploy
only:
- main
image: alpine:latest
services:
- docker:dind
before_script:
- apk add --no-cache openssh-client
# On écrit la clé privée stockée dans la variable GITLAB_SSH_KEY
- echo "$GITLAB_SSH_KEY" > /tmp/id_ecdsa
- chmod 600 /tmp/id_ecdsa
script:
- ssh -o StrictHostKeyChecking=no -i /tmp/id_ecdsa $SSH_USER@$SSH_SERVER "bash /home/stagiaire/myproject/deploy.sh"