Laravel Envoy é uma ferramenta para executar tarefas comuns executadas em servidores remotos.
Acredito Envoy
é subestimado; Não vejo isso sendo usado com muita frequência, embora sempre o tenha achado muito útil. Neste artigo, exploraremos como Envoy
pode ajudar a aumentar sua produtividade🚀.
Laravel Envoy não é exclusivo para desenvolvedores Laravel ou limitado a projetos Laravel, qualquer pessoa pode usá-lo ❤️.
Primeiro, vamos discutir dois conceitos-chave no Envoy
:
Tarefas : representa uma ação específica, como atualizar o servidor ou clonar um repositório.
Histórias : que é uma coleção de tarefas.
Isso é tudo que você precisa saber por enquanto; você sempre pode ler sobre todos os recursos nos documentos .
Neste artigo, automatizaremos duas coisas que a maioria dos desenvolvedores faz ao implantar seus aplicativos:
Configurando o Nginx.
Gerar chaves SSH e adicioná-las ao GitHub para poder acessar repositórios privados.
Sim, eu sei, na maioria das vezes Envoy
é usado para fluxos de trabalho de CI/CD, mas pode fazer TUDO , literalmente.
Primeiro, vamos criar um diretório:
mkdir tuto && cd $_
$ take tuto
se você estiver usandozsh
.
Instale Envoy
executando o seguinte comando:
composer require laravel/envoy --dev
Certifique-se de ter o compositor instalado.
Agora, crie um arquivo chamado Envoy.blade.php
. Sim, usaremos a sintaxe Blade
, muito legal, certo?
touch Envoy.blade.php
É isso! Tudo que você precisa é de um único script. Não precisa ser específico do Laravel ou de qualquer projeto relacionado ao Laravel. Vamos começar a automatizar! 😁
Temos um servidor totalmente novo e queremos configurar o Nginx. Se decompormos o processo, seria assim:
Isso é exatamente o que faremos com Envoy
; pense em cada etapa como uma Task
e todo o processo como uma Story
.
Então, vamos traduzir o que acabamos de dizer em uma história:
@servers(['web' => '[email protected]', 'local' => '127.0.0.1']) @story('setup-nginx') update-server install-nginx copy-nginx-stub configure-nginx @endstory
A diretiva
@servers
é usada para especificar os servidores nos quais executaremos nossas tarefas posteriormente.
Agora podemos prosseguir com a definição de cada tarefa 😁
Nossa primeira tarefa update-server
garantirá que os pacotes e dependências do servidor estejam atualizados:
@task('update-server', ['on' => ['web']]) echo "Updating server..." apt update && apt upgrade -y @endtask
A segunda tarefa install-nginx
instalará o Nginx em nosso 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 removemos o link padrão do Nginx e criamos um novo para nosso aplicativo, com o nome vindo da variável $application_name
.
Para poder usar essa variável, você precisa declará-la, então precisamos incluir a diretiva @setup
:
@setup $application_name = 'your-application-name'; @endsetup
Agora podemos passar para a terceira tarefa copy-nginx-stub
. No meu caso, estou implantando uma aplicação Laravel, então usarei o arquivo de configuração Nginx fornecido pela documentação , com alguns ajustes. Se estiver implantando um aplicativo diferente, você poderá aplicar o mesmo conceito ao seu próprio arquivo de configuração.
No diretório que acabamos de criar, execute o seguinte comando:
mkdir stubs; nano stubs/nginx.conf
Em seguida, cole o seguinte conteúdo no editor, salve-o e saia:
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; } }
O public_ip
e app_name
são espaços reservados por enquanto e serão atualizados automaticamente com nossas variáveis.
Vamos prosseguir para escrever a tarefa em si:
@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 tarefa será executada em nossa máquina local em vez de no servidor remoto. Especificamos isso usando
'on' => 'local'
.
E não esqueça de atualizar a diretiva @setup
com as variáveis necessárias:
@setup $application_name = 'your-application-name'; $production_port = 22; $production_host = '[email protected]'; @endsetup
A quarta e última tarefa configure-nginx
atualizará os espaços reservados, para que possamos servir o aplicativo corretamente:
@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
Observe o comando
cd
. Isso ocorre porque cada tarefa é executada separadamente, portanto, sempre inicia no diretório inicial do servidor remoto.
Já criamos o link simbólico ao instalar o Nginx, não precisamos nos preocupar com isso agora.
E terminamos esta seção! Seu script deve ficar assim:
@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
Agora que configuramos o Nginx e ele está pronto para atender nossa aplicação, precisamos gerar chaves SSH e adicionar a chave pública ao GitHub para que possamos extrair os repositórios privados.
Para isso, usaremos a API REST do GitHub , portanto, antes de começarmos, você precisa criar um token .
Ao criar seu token, certifique-se de selecionar apenas o escopo "admin:public_key".
Agora que você criou seu token, vamos começar definindo algumas variáveis:
@setup $ssh_key = '~/.ssh/id_rsa_github'; $github_api_key = 'your-github-token'; $email = '[email protected]'; @endsetup
Neste ponto, você deve estar se perguntando sobre as etapas envolvidas neste processo. Bem, podemos dividir isso em duas etapas:
Gerar chaves SSH
Copie a chave pública para GitHub
Mais uma vez, este processo será a nossa história:
@story('setup-ssh-keys') generate-ssh-keys add-ssh-keys-to-github @endstory
A primeira tarefa, generate-ssh-keys
, pode ser realizada executando um único comando:
@task('generate-ssh-keys', ['on' => ['web']]) echo "Generating ssh keys..." ssh-keygen -t ed25519 -f {{ $ssh_key }} -N '' -q -C "{{ $email }}" @endtask
Depois de gerarmos nossas chaves SSH, podemos adicionar a chave pública ao GitHub usando a API do GitHub. Isso pode ser feito com uma única solicitação:
@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
E é isso! Se você visitar as configurações do desenvolvedor do GitHub, deverá ver sua chave recém-criada.
Combinando as duas seções, seu script final deverá ficar assim:
@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
Aprendemos como usar Envoy
para automatizar tarefas comuns. É uma ferramenta poderosa com ainda mais recursos do que os que exploramos aqui. Não se limite apenas a implantar seus aplicativos; Envoy
pode automatizar QUALQUER comando de terminal, literalmente qualquer coisa que vier à mente.
Da próxima vez que você repetir os mesmos comandos, considere usá-lo, prometo que faz muito mais do que CI/CD 😛😛