Laravel Envoy est un outil permettant d'exécuter les tâches courantes que vous exécutez sur vos serveurs distants.
Je pense Envoy
est sous-estimé ; Je ne le vois pas utilisé très souvent même si je l’ai toujours trouvé très utile. Dans cet article, nous explorerons comment Envoy
peut vous aider à augmenter votre productivité🚀.
Laravel Envoy n'est pas exclusif aux développeurs Laravel ni limité aux projets Laravel, tout le monde peut l'utiliser ❤️.
Tout d'abord, discutons de deux concepts clés dans Envoy
:
Tâches : Cela représente une action spécifique comme la mise à jour du serveur ou le clonage d'un référentiel.
Stories : qui est une collection de tâches.
C'est tout ce que vous devez savoir pour l'instant ; vous pouvez toujours en savoir plus sur toutes les fonctionnalités dans la documentation .
Dans cet article, nous allons automatiser 2 choses que la plupart des développeurs font lors du déploiement de leurs applications :
Configuration de Nginx.
Générer des clés SSH et les ajouter à GitHub pour pouvoir accéder aux référentiels privés.
Oui, je sais, la plupart du temps, Envoy
est utilisé pour les flux de travail CI/CD, mais il peut TOUT faire, littéralement.
Tout d'abord, créons un répertoire :
mkdir tuto && cd $_
$ take tuto
si vous utilisezzsh
.
Installez Envoy
en exécutant la commande suivante :
composer require laravel/envoy --dev
Assurez-vous que Composer est installé.
Maintenant, créez un fichier appelé Envoy.blade.php
. Oui, nous utiliserons la syntaxe Blade
, super cool, non ?
touch Envoy.blade.php
C'est ça! Tout ce dont vous avez besoin est un seul script. Il n'est pas nécessaire que cela soit spécifique à Laravel ou à tout projet lié à Laravel. Commençons par l'automatisation ! 😁
Nous avons un tout nouveau serveur et nous souhaitons configurer Nginx. Si nous décomposons le processus, cela donnerait ceci :
C'est exactement ce que nous allons faire avec Envoy
; considérez chaque étape comme une Task
et l'ensemble du processus comme une Story
.
Alors, traduisons ce que nous venons de dire en une histoire :
@servers(['web' => '[email protected]', 'local' => '127.0.0.1']) @story('setup-nginx') update-server install-nginx copy-nginx-stub configure-nginx @endstory
La directive
@servers
est utilisée pour spécifier les serveurs sur lesquels nous exécuterons nos tâches ultérieurement.
Maintenant, nous pouvons procéder à la définition de chaque tâche 😁
Notre première tâche update-server
veillera à ce que les packages et dépendances du serveur soient à jour :
@task('update-server', ['on' => ['web']]) echo "Updating server..." apt update && apt upgrade -y @endtask
La deuxième tâche install-nginx
installera Nginx sur notre serveur :
@task('install-nginx', ['on' => ['web']]) echo "Installing nginx..." apt install nginx -y rm /etc/nginx/sites-enabled/default /etc/nginx/sites-available/default touch /etc/nginx/sites-available/{{ $application_name }}.conf ln -s /etc/nginx/sites-available/{{ $application_name }}.conf /etc/nginx/sites-enabled/{{ $application_name }}.conf @endtask
Notez que nous avons supprimé le lien Nginx par défaut et en avons créé un nouveau pour notre application, dont le nom provient de la variable $application_name
.
Pour pouvoir utiliser cette variable, vous devez la déclarer, nous devons donc inclure la directive @setup
:
@setup $application_name = 'your-application-name'; @endsetup
Maintenant, nous pouvons passer à la troisième tâche copy-nginx-stub
. Dans mon cas, je déploie une application Laravel, j'utiliserai donc le fichier de configuration Nginx fourni par la documentation , avec quelques ajustements. Si vous déployez une autre application, vous pouvez appliquer le même concept à votre propre fichier de configuration.
Dans le répertoire que nous venons de créer, exécutez la commande suivante :
mkdir stubs; nano stubs/nginx.conf
Ensuite, collez le contenu suivant dans l'éditeur, enregistrez-le et quittez :
server { listen 80; listen [::]:80; server_name public_ip; root /var/www/app_name/public; add_header X-Frame-Options "SAMEORIGIN"; add_header X-Content-Type-Options "nosniff"; index index.php; charset utf-8; location / { try_files $uri $uri/ /index.php?$query_string; } location = /favicon.ico { access_log off; log_not_found off; } location = /robots.txt { access_log off; log_not_found off; } error_page 404 /index.php; location ~ \.php$ { fastcgi_pass unix:/var/run/php/php8.0-fpm.sock; fastcgi_param SCRIPT_FILENAME $realpath_root$fastcgi_script_name; include fastcgi_params; } location ~ /\.(?!well-known).* { deny all; } }
public_ip
et app_name
sont des espaces réservés pour le moment et seront automatiquement mis à jour avec nos variables.
Passons à l'écriture de la tâche elle-même :
@task('copy-nginx-stub', ['on' => 'local']) scp -P{{ $production_port }} -r ./stubs/nginx.conf {{ $production_host }}:/etc/nginx/sites-available/{{ $application_name }}.conf @endtask
Cette tâche sera exécutée sur notre machine locale au lieu du serveur distant. Nous spécifions cela en utilisant
'on' => 'local'
.
Et n'oubliez pas de mettre à jour la directive @setup
avec les variables nécessaires :
@setup $application_name = 'your-application-name'; $production_port = 22; $production_host = '[email protected]'; @endsetup
La quatrième et dernière tâche configure-nginx
mettra à jour les espaces réservés, afin que nous puissions servir correctement l'application :
@task('configure-nginx', ['on' => 'web']) echo "Configuring nginx..." cd /etc/nginx/sites-available/ sed -i 's/app_name/{{ $application_name }}/g' {{ $application_name }}.conf sed -i 's/public_ip/{{ $production_ip }}/g' {{ $application_name }}.conf @endtask
Notez la commande
cd
. En effet, chaque tâche est exécutée séparément et démarre donc toujours à partir du répertoire personnel du serveur distant.
Nous avons déjà créé le lien symbolique lors de l'installation de Nginx, nous n'avons plus à nous en préoccuper maintenant.
Et nous en avons fini avec cette section ! Votre script devrait ressembler à ceci :
@servers(['web' => '[email protected]', 'local' => '127.0.0.1']) @setup $application_name = 'your-application-name'; $production_port = 22; $production_host = '[email protected]'; @endsetup @story('setup-nginx') update-server install-nginx copy-nginx-stub configure-nginx @endstory @task('update-server', ['on' => ['web']]) echo "Updating server..." apt update && apt upgrade -y @endtask @task('install-nginx', ['on' => ['web']]) echo "Installing nginx..." apt install nginx -y rm /etc/nginx/sites-enabled/default /etc/nginx/sites-available/default touch /etc/nginx/sites-available/{{ $application_name }}.conf ln -s /etc/nginx/sites-available/{{ $application_name }}.conf /etc/nginx/sites-enabled/{{ $application_name }}.conf @endtask @task('copy-nginx-stub', ['on' => 'local']) scp -P{{ $production_port }} -r ./stubs/nginx.conf {{ $production_host }}:/etc/nginx/sites-available/{{ $application_name }}.conf @endtask @task('configure-nginx', ['on' => 'web']) echo "Configuring nginx..." cd /etc/nginx/sites-available/ sed -i 's/app_name/{{ $application_name }}/g' {{ $application_name }}.conf sed -i 's/public_ip/{{ $production_ip }}/g' {{ $application_name }}.conf @endtask
Maintenant que nous avons configuré Nginx et qu'il est prêt à servir notre application, nous devons générer des clés SSH et ajouter la clé publique à GitHub afin de pouvoir extraire les référentiels privés.
Pour cela, nous utiliserons l'API REST GitHub , donc avant de commencer, vous devez créer un jeton .
Lors de la création de votre jeton, assurez-vous de sélectionner uniquement la portée « admin:public_key ».
Maintenant que vous avez créé votre token, commençons par définir quelques variables :
@setup $ssh_key = '~/.ssh/id_rsa_github'; $github_api_key = 'your-github-token'; $email = '[email protected]'; @endsetup
À ce stade, vous vous interrogez peut-être sur les étapes impliquées dans ce processus. Eh bien, nous pouvons le décomposer en deux étapes :
Générer des clés SSH
Copiez la clé publique sur GitHub
Une fois de plus, ce processus sera notre histoire :
@story('setup-ssh-keys') generate-ssh-keys add-ssh-keys-to-github @endstory
La première tâche, generate-ssh-keys
, peut être effectuée en exécutant une seule commande :
@task('generate-ssh-keys', ['on' => ['web']]) echo "Generating ssh keys..." ssh-keygen -t ed25519 -f {{ $ssh_key }} -N '' -q -C "{{ $email }}" @endtask
Une fois que nous avons généré nos clés SSH, nous pouvons ajouter la clé publique à GitHub à l'aide de l'API GitHub. Cela peut être fait avec une seule demande :
@task('add-ssh-keys-to-github', ['on' => ['web']]) echo "Adding ssh keys to github..." key=$(cat {{ $ssh_key }}.pub) curl --request POST \ --url https://api.github.com/user/keys \ --header 'Accept: application/vnd.github+json' \ --header 'Authorization: Bearer {{ $github_api_key }}' \ --header 'Content-Type: application/json' \ --header 'X-GitHub-Api-Version: 2022-11-28' \ --data '{ "title": "[Envoy] Public key", "key": "'"$key"'" }' @endtask
Et c'est tout! Si vous visitez vos paramètres de développeur GitHub, vous devriez voir votre clé nouvellement créée.
En combinant les deux sections, votre script final devrait ressembler à ceci :
@servers(['web' => '[email protected]', 'local' => '127.0.0.1']) @setup $application_name = 'your-application-name'; $production_port = 22; $production_host = '[email protected]'; $ssh_key = '~/.ssh/id_rsa_github'; $github_api_key = 'your-github-token'; $email = '[email protected]'; @endsetup @story('setup-nginx') update-server install-nginx copy-nginx-stub configure-nginx @endstory @story('setup-ssh-keys') generate-ssh-keys add-ssh-keys-to-github @endstory @task('update-server', ['on' => ['web']]) echo "Updating server..." apt update && apt upgrade -y @endtask @task('install-nginx', ['on' => ['web']]) echo "Installing Nginx..." apt install nginx -y rm /etc/nginx/sites-enabled/default /etc/nginx/sites-available/default touch /etc/nginx/sites-available/{{ $application_name }}.conf ln -s /etc/nginx/sites-available/{{ $application_name }}.conf /etc/nginx/sites-enabled/{{ $application_name }}.conf @endtask @task('copy-nginx-stub', ['on' => 'local']) scp -P{{ $production_port }} -r ./stubs/nginx.conf {{ $production_host }}:/etc/nginx/sites-available/{{ $application_name }}.conf @endtask @task('configure-nginx', ['on' => 'web']) echo "Configuring nginx..." cd /etc/nginx/sites-available/ sed -i 's/app_name/{{ $application_name }}/g' {{ $application_name }}.conf sed -i 's/public_ip/{{ $production_ip }}/g' {{ $application_name }}.conf @endtask @task('generate-ssh-keys', ['on' => ['web']]) echo "Generating ssh keys..." ssh-keygen -t ed25519 -f {{ $ssh_key }} -N '' -q -C "{{ $email }}" @endtask @task('add-ssh-keys-to-github', ['on' => ['web']]) echo "Adding ssh keys to github..." key=$(cat {{ $ssh_key }}.pub) curl --request POST \ --url https://api.github.com/user/keys \ --header 'Accept: application/vnd.github+json' \ --header 'Authorization: Bearer {{ $github_api_key }}' \ --header 'Content-Type: application/json' \ --header 'X-GitHub-Api-Version: 2022-11-28' \ --data '{ "title": "creating from script", "key": "'"$key"'" }' @endtask
Nous avons appris à utiliser Envoy
pour automatiser les tâches courantes. C'est un outil puissant avec encore plus de fonctionnalités que celles que nous avons explorées ici. Ne vous limitez pas au simple déploiement de vos applications ; Envoy
peut automatiser N'IMPORTE QUELLE commande de terminal, littéralement tout ce qui vous vient à l'esprit.
La prochaine fois que vous vous retrouverez à répéter les mêmes commandes, pensez à l'utiliser, je vous promets qu'il fait bien plus que CI/CD 😛😛