Déploiement natif
Cette méthode de déploiement automatisé réalise les étapes d’installation / mise à jour / configuration à destination de projets qui seront instanciés nativement sur le serveur.
Elle peut s’intégrer dans une pipeline de la CI de Gitlab, et son principe repose simplement sur Git, en indiquant la branche à partir de laquelle on souhaite déployer le code dans le fichier .gitlab-ci.yml
.
Sources
Le projet est hébergé dans un Gitlab, dans un répertoire nommé “web”.
Les étapes de l’intégration continue sont décrites dans le fichier .gitlab-ci.yml
.
web/
.gitlab-ci.yml
Le script de deploiement s’appelle via la commande deploy
que vous pouvez préfixer ainsi pour le déploiement en production: PROD=true deploy
Variables d’environnement
Les variables obligatoires pour le déploiement sont définies par Bearstech:
DEPLOY_HOST
: nom de la machine hôteDEPLOY_USER
: utilisateur autorisé à déployerDEPLOY_KEY
: clé de l’utilisateurDEPLOY_HOST_KEY
: permet d’authentifier l’hôte
Des variables spécifiques peuvent être définies dans les settings CI/CD du projet et seront propagées vers un fichier
.env
à la racine du repository (ex :DEPLOY_MYTOKEN
défini dans Gitlab deviendraMYTOKEN
dans le fichier ~/root/.env)
Processus de déploiement
- Pour le premier déploiement, le repository est cloné dans le
$HOME/root
du serveur - Pour les déploiements suivants, un “nettoyage” (checkout) du repository sur le serveur cible est réalisé pour s’assurer de ne pas avoir de conflits, puis mise-à-jour du repository (pull) vers le commit correspondant au déploiement (checkout)
- Le dépôt git doit contenir un répertoire (“web”) qui stocke les fichiers à exposer publiquement
- Dans un cas ultra-simple de déploiement d’un projet de type LAMP, le DocumentRoot pointe vers
~/root/web
, le code se met-à-jour via legit pull
, les développeurs doivent juste bien penser à maintenir le.gitignore
pour éviter de surcharger le repository Git avec des assets statiques (par exemple, on exclue bien sonweb/wp-content/uploads
).
Post-deploy
Il est possible de définir des scripts “post-deploy” qui seront exécutés à la fin du déploiement (par exemple pour vider les caches de l’application). Ils doivent être définis dans l’ordre, dans un dossier
.deploy.d
. Toutes les variablesDEPLOY_*
sont accessibles lors de l’exécution de ces scriptsAttention, les 4 variables obligatoires définies ci-dessus (
HOST
,USER
, …) sont réservées et ne sont pas propagées dans le.env
. Si l’application a besoin d’une de ces variables, il faut gérer ce cas particulier dans un script dans le dossier.deploy.d
.Par exemple, pour définir une variable d’environnement qui définit un HOST personnalisé pour votre application (un domaine racine différent du HOST du serveur), on peut l’ajouter au
.env
de cette manière, via ce scriptmy-super-project/.deploy.d/011-set-host-variable
:#! /bin/bash export HOST="${MY_HOST}" echo "HOST=${MY_HOST}" >> ~/root/.env
Instancier un service
Si l’application doit être lancée sur le serveur (pour les applications Nodejs, Python, …), les dévelopeurs ont accès à Systemd
au niveau utilisateur et peuvent donc gérer eux-mêmes les actions sur le service et son évolution:
Créer un service et le versionner dans le projet
my-super-project/systemd/my-super-service.service
:[Unit] Description=My super service for my super project [Service] ExecStart=~/root/start-server.sh Restart=always RestartSec=180 [Install] WantedBy=default.target
Créer un script “post-deploy” et le versionner dans le dossier
.deploy.d
du projet (my-super-project/.deploy.d/022-install-service
):#! /bin/bash mkdir -p ~/.config/systemd/user/ cp ~/root/systemd/my-super-service.service ~/.config/systemd/user/my-super-service.service systemctl --user daemon-reload systemctl restart my-super-service
Tâches planifiées
On peut déployer ses tâches planifiées via un timer systemd (voir au dessus) ou une classique crontab versionnée dans votre dépôt:
- Définir la tâche qui lancera le cronjob dans
my-super-project/crontab
0 * * * * /bin/bash $HOME/root/hourly-script
- Créer un script “post-deploy” pour installer le cronjob
my-super-project/.deploy.d/033-install-cron
:
#! /bin/bash
crontab ~/root/crontab
Déploiement sur un serveur mutualisé
S’applique dans le cas d’un serveur avec plusieurs applications et multi-environnements. Les variables sont à définir dans les settings CI/CD du projet.
- Forcer la variable
DEPLOY_USER
à ‘deploy’, cet utilisateur spécial à les droits de création d’environnements - Il faut spécifier l’URL du site au script de déploiement en argument (
script: deploy my-super-site.com
) - Vous pouvez aussi utiliser les variables suivantes:
DEPLOY_ALIASES
: domaines à utiliser comme aliases (les redirections adéquates sont à gérer dans votre .htaccess)DEPLOY_SSH_KEY_FILE
: chemin vers un fichier contenant les clefs SSH à autoriser (peut être versionné dans votre repository par exemple)DEPLOY_BASIC_AUTH
: mot de passe pour une basic auth (l’utilisateur est le nom de votre projet gitlab comme il apparaît dans l’url: https://[GITLAB_URL]/[GROUP]/[PROJECT] ->GROUP-PROJECT
)DEPLOY_ENABLE_PHP
: définit si l’environnement utilise du PHP (par défaut à true)DEPLOY_ENABLE_MYSQL
: définit si l’environnement a besoin d’une base MySQL (par défaut à true)
Gestion des certificats
DEPLOY_TLS_MODE
: mode TLS (none
,letsencrypt
oumanual
), par défaut ànone
(certificat “snakeoil”)DEPLOY_TLS_CERTIFICATE
: certificat à utiliser siTLS_MODE
est défini àmanual
(par défaut à/etc/ssl/certs/DOMAIN.TLD.crt
)DEPLOY_TLS_KEY
: fichier clef à utiliser siTLS_MODE
est défini àmanual
(par défaut à/etc/ssl/private/DOMAIN.TLD.key
)DEPLOY_TLS_CHAIN
: chaîne de certificats à utiliser siTLS_MODE
est défini àmanual
(par défaut à/etc/ssl/certs/DOMAIN.TLD.chain
)
Utilisation dans le fichier .gitlab-ci.yml
A la racine du projet, placer le fichier .gitlab-ci.yml. Avec l’exemple ci-dessous, la préproduction sera déployée dans un serveur mutualisé, et la production sur un dédié:
default:
image: bearstech/deploy
stages:
- deploy-preprod
- deploy-prod
staging:
stage: deploy-preprod
environment:
name: preprod
script:
- deploy my-super-site-preprod.bearstech.dev
production:
stage: deploy-prod
environment:
name: prod
script:
- PROD=true deploy
only:
refs:
- main
when: manual
Ici, le déploiement se fait automatiquement sur la préproduction à chaque commit. Pour la production, le déploiement se déclenche uniquement pour les commits sur la branche ‘main’ et via une action manuelle de votre part.