paint-brush
Laravel Envoy - 如何自动化无聊的事情经过@oussamamater
1,009 讀數
1,009 讀數

Laravel Envoy - 如何自动化无聊的事情

经过 Oussama Mater9m2024/07/10
Read on Terminal Reader

太長; 讀書

Laravel Envoy 可以帮助您自动执行繁琐的任务,它能做的远不止 CI/CD。让我们看看如何使用它来自动设置 Nginx 并将 SSH 密钥添加到 GitHub。
featured image - Laravel Envoy - 如何自动化无聊的事情
Oussama Mater HackerNoon profile picture

Laravel Envoy 是一个用于执行在远程服务器上运行的常见任务的工具。


我认为Envoy被低估了;尽管我一直觉得它非常有用,但我并不经常使用它。在本文中,我们将探讨Envoy如何帮助您提高工作效率🚀。


Laravel Envoy 并非 Laravel 开发人员专属,也不仅限于 Laravel 项目,任何人都可以使用它 ❤️。


首先,我们来讨论一下Envoy中的两个关键概念:


  1. 任务:这代表特定的操作,例如更新服务器或克隆存储库。


  2. 故事:是任务的集合。


这就是您现在需要知道的全部内容;您可以随时在文档中阅读有关所有功能的信息。

我们正在自动化什么?

在本文中,我们将自动执行大多数开发人员在部署应用程序时所做的两件事:


  1. 配置 Nginx。


  2. 生成 SSH 密钥并将其添加到 GitHub 以便能够访问私有存储库。


是的,我知道,大多数时候Envoy用于 CI/CD 工作流,但实际上它可以做任何事情

Envoy 设置

首先,让我们创建一个目录:

 mkdir tuto && cd $_


如果您使用zsh$ take tuto


通过运行以下命令安装Envoy

 composer require laravel/envoy --dev


确保您已经安装了 Composer。


现在,创建一个名为Envoy.blade.php的文件。是的,我们将使用Blade语法,超酷吧?

 touch Envoy.blade.php


就是这样!你只需要一个脚本。它不必特定于 Laravel 或任何与 Laravel 相关的项目。让我们开始自动化吧!😁

配置 Nginx

我们有一台全新的服务器,我们想设置 Nginx。如果我们分解这个过程,它将是这样的:


  1. 更新服务器
  2. 安装 Nginx
  3. 配置 Nginx


这正是我们将要用Envoy做的事情;将每个步骤视为一个Task ,将整个过程视为一个Story


那么,让我们把刚才所说的内容转化成一个故事:

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


@servers指令用于指定我们稍后将运行任务的服务器。


现在,我们可以继续定义每个任务了😁


我们的第一个任务update-server将确保服务器的包和依赖项是最新的:

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


第二个任务install-nginx将在我们的服务器上安装 Nginx:

 @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


请注意,我们已经删除了默认的 Nginx 链接并为我们的应用程序创建了一个新的链接,其名称来自$application_name变量。


为了能够使用该变量,您需要声明它,因此我们需要包含@setup指令:

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

现在,我们可以转到第三个任务copy-nginx-stub 。 就我而言,我正在部署一个 Laravel 应用程序,因此我将使用docs提供的 Nginx 配置文件,并进行一些调整。 如果您要部署其他应用程序,则可以将相同的概念应用于您自己的配置文件。


在我们刚刚创建的目录中,运行以下命令:

 mkdir stubs; nano stubs/nginx.conf


然后,将以下内容粘贴到编辑器中,保存并退出:

 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_ipapp_name目前是占位符,将使用我们的变量自动更新。


让我们继续编写任务本身:

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


此任务将在本地机器上执行,而不是在远程服务器上执行。我们使用'on' => 'local'来指定。


并且不要忘记使用必要的变量来更新@setup指令:

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



第四个也是最后一个任务configure-nginx将更新占位符,以便我们可以正确地提供应用程序:

 @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


注意cd命令。这是因为每个任务都是单独执行的,所以它总是从远程服务器的主目录开始。


我们在安装 Nginx 时已经创建了符号链接,现在不必担心它。


我们已经完成了这一部分!您的脚本应如下所示:

 @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

SSH 密钥配置

现在我们已经配置了 Nginx,它已准备好为我们的应用程序提供服务,我们需要生成 SSH 密钥并将公钥添加到 GitHub,以便我们可以拉取私有存储库。


为此,我们将使用GitHub REST API ,因此在开始之前,您需要创建一个令牌


创建令牌时,请确保只选择“admin:public_key”范围。


现在您已经创建了令牌,让我们首先定义一些变量:

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

此时,您可能想知道此过程涉及的步骤。好吧,我们可以将其分为两个步骤:


  1. 生成 SSH 密钥


  2. 将公钥复制到 GitHub


再次重申一下,这个过程就是我们的故事:

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


第一个任务generate-ssh-keys可以通过运行单个命令来完成:

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


生成 SSH 密钥后,我们可以使用 GitHub API 将公钥添加到 GitHub。只需一个请求即可完成此操作:

 @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

就这样!如果你访问你的 GitHub 开发者设置,你应该会看到你新创建的密钥。


通过合并这两个部分,您的最终脚本应如下所示:

 @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

结论

我们学习了如何使用Envoy来自动化常见任务。这是一个功能强大的工具,其功能比我们在此处探索的还要多。不要局限于部署应用程序; Envoy可以自动化任何终端命令,几乎任何你能想到的命令。


下次你发现自己重复相同的命令时,请考虑使用它,我向你保证它比 CI/CD 功能强大得多😛😛