paint-brush
Laravel Envoy: cómo automatizar las cosas aburridaspor@oussamamater
1,009 lecturas
1,009 lecturas

Laravel Envoy: cómo automatizar las cosas aburridas

por Oussama Mater9m2024/07/10
Read on Terminal Reader

Demasiado Largo; Para Leer

Laravel Envoy puede ayudarle a automatizar tareas tediosas y puede hacer mucho más que solo CI/CD. Veamos cómo podemos usarlo para automatizar la configuración de Nginx y agregar claves SSH a GitHub.
featured image - Laravel Envoy: cómo automatizar las cosas aburridas
Oussama Mater HackerNoon profile picture

Laravel Envoy es una herramienta para ejecutar tareas comunes que ejecuta en sus servidores remotos.


Creo que Envoy está subestimado; No veo que se use muy a menudo aunque siempre me ha resultado súper útil. En este artículo, exploraremos cómo Envoy puede ayudarlo a aumentar su productividad🚀.


Laravel Envoy no es exclusivo de los desarrolladores de Laravel ni se limita a proyectos de Laravel, cualquiera puede usarlo ❤️.


Primero, analicemos dos conceptos clave en Envoy :


  1. Tareas : esto representa una acción específica como actualizar el servidor o clonar un repositorio.


  2. Historias : que es una colección de Tareas.


Eso es todo lo que necesitas saber por ahora; Siempre puedes leer sobre todas las funciones en los documentos .

¿Qué estamos automatizando?

En este artículo, automatizaremos 2 cosas que hacen la mayoría de los desarrolladores al implementar sus aplicaciones:


  1. Configurando Nginx.


  2. Generar claves SSH y agregarlas a GitHub para poder acceder a repositorios privados.


Sí, lo sé, la mayor parte del tiempo Envoy se utiliza para flujos de trabajo de CI/CD, pero puede hacer TODO , literalmente.

Configuración del enviado

Primero, creemos un directorio:

 mkdir tuto && cd $_


$ take tuto si estás usando zsh .


Instale Envoy ejecutando el siguiente comando:

 composer require laravel/envoy --dev


Asegúrate de tener el compositor instalado.


Ahora, crea un archivo llamado Envoy.blade.php . Sí, usaremos la sintaxis Blade , genial, ¿verdad?

 touch Envoy.blade.php


¡Eso es todo! Todo lo que necesitas es un único script. No tiene que ser específico de Laravel ni de ningún proyecto relacionado con Laravel. ¡Empecemos a automatizar! 😁

Configurar Nginx

Tenemos un servidor nuevo y queremos configurar Nginx. Si desglosamos el proceso, quedaría así:


  1. Actualizar el servidor
  2. Instalar Nginx
  3. Configurar Nginx


Eso es exactamente lo que haremos con Envoy ; Piense en cada paso como una Task y en todo el proceso como una Story .


Entonces, traduzcamos lo que acabamos de decir en una historia:

 @servers(['web' => '[email protected]', 'local' => '127.0.0.1']) @story('setup-nginx') update-server install-nginx copy-nginx-stub configure-nginx @endstory


La directiva @servers se utiliza para especificar los servidores en los que ejecutaremos nuestras tareas más adelante.


Ahora podemos proceder a definir cada tarea 😁


Nuestra primera tarea update-server garantizará que los paquetes y dependencias del servidor estén actualizados:

 @task('update-server', ['on' => ['web']]) echo "Updating server..." apt update && apt upgrade -y @endtask


La segunda tarea install-nginx instalará Nginx en nuestro servidor:

 @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


Observe que eliminamos el enlace Nginx predeterminado y creamos uno nuevo para nuestra aplicación, con el nombre proveniente de la variable $application_name .


Para poder usar esa variable, debes declararla, por lo que debemos incluir la directiva @setup :

 @setup $application_name = 'your-application-name'; @endsetup

Ahora podemos pasar a la tercera tarea copy-nginx-stub . En mi caso, estoy implementando una aplicación Laravel, por lo que usaré el archivo de configuración de Nginx proporcionado por los documentos , con algunos ajustes. Si está implementando una aplicación diferente, puede aplicar el mismo concepto a su propio archivo de configuración.


En el directorio que acabamos de crear, ejecute el siguiente comando:

 mkdir stubs; nano stubs/nginx.conf


Luego, pegue el siguiente contenido en el editor, guárdelo y salga:

 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 y app_name son marcadores de posición por ahora y se actualizarán automáticamente con nuestras variables.


Pasemos a escribir la tarea en sí:

 @task('copy-nginx-stub', ['on' => 'local']) scp -P{{ $production_port }} -r ./stubs/nginx.conf {{ $production_host }}:/etc/nginx/sites-available/{{ $application_name }}.conf @endtask


Esta tarea se ejecutará en nuestra máquina local en lugar del servidor remoto. Especificamos esto usando 'on' => 'local' .


Y no olvides actualizar la directiva @setup con las variables necesarias:

 @setup $application_name = 'your-application-name'; $production_port = 22; $production_host = '[email protected]'; @endsetup



La cuarta y última tarea configure-nginx actualizará los marcadores de posición, para que podamos servir la aplicación correctamente:

 @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


Tenga en cuenta el comando cd . Esto se debe a que cada tarea se ejecuta por separado, por lo que siempre comienza desde el directorio de inicio del servidor remoto.


Ya creamos el enlace simbólico al instalar Nginx, no tenemos que preocuparnos por eso ahora.


¡Y hemos terminado con esta sección! Su script debería verse así:

 @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

Configuración de clave SSH

Ahora que configuramos Nginx y está listo para servir nuestra aplicación, necesitamos generar claves SSH y agregar la clave pública a GitHub para que podamos extraer los repositorios privados.


Para esto, usaremos la API REST de GitHub , por lo que antes de comenzar, debe crear un token .


Al crear su token, asegúrese de seleccionar solo el alcance "admin:public_key".


Ahora que creaste tu token, comencemos por definir algunas variables:

 @setup $ssh_key = '~/.ssh/id_rsa_github'; $github_api_key = 'your-github-token'; $email = '[email protected]'; @endsetup

En este punto, es posible que se pregunte acerca de los pasos involucrados en este proceso. Bueno, podemos dividirlo en dos pasos:


  1. Generar claves SSH


  2. Copie la clave pública a GitHub


Una vez más, este proceso será nuestra historia:

 @story('setup-ssh-keys') generate-ssh-keys add-ssh-keys-to-github @endstory


La primera tarea, generate-ssh-keys , se puede realizar ejecutando un solo comando:

 @task('generate-ssh-keys', ['on' => ['web']]) echo "Generating ssh keys..." ssh-keygen -t ed25519 -f {{ $ssh_key }} -N '' -q -C "{{ $email }}" @endtask


Una vez que hayamos generado nuestras claves SSH, podemos agregar la clave pública a GitHub usando la API de GitHub. Esto se puede hacer con una sola solicitud:

 @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

¡Y eso es! Si visita la configuración de desarrollador de GitHub, debería ver su clave recién creada.


Al combinar las dos secciones, su guión final debería verse así:

 @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

Conclusión

Aprendimos a utilizar Envoy para automatizar tareas comunes. Es una herramienta poderosa con incluso más capacidades de las que hemos explorado aquí. No se limite sólo a implementar sus aplicaciones; Envoy puede automatizar CUALQUIER comando de terminal, literalmente cualquier cosa que se le ocurra.


La próxima vez que te encuentres repitiendo los mismos comandos, considera usarlo, te prometo que hace mucho más que CI/CD 😛😛