Laravel Envoy 是一个用于执行在远程服务器上运行的常见任务的工具。 我认为 被低估了;尽管我一直觉得它非常有用,但我并不经常使用它。在本文中,我们将探讨 如何帮助您提高工作效率🚀。 Envoy Envoy Laravel Envoy 并非 Laravel 开发人员专属,也不仅限于 Laravel 项目, 都可以使用它 ❤️。 任何人 首先,我们来讨论一下 中的两个关键概念: Envoy :这代表特定的操作,例如更新服务器或克隆存储库。 任务 :是任务的集合。 故事 这就是您现在需要知道的全部内容;您可以随时在 中阅读有关所有功能的信息。 文档 我们正在自动化什么? 在本文中,我们将自动执行大多数开发人员在部署应用程序时所做的两件事: 配置 Nginx。 生成 SSH 密钥并将其添加到 GitHub 以便能够访问私有存储库。 是的,我知道,大多数时候 用于 CI/CD 工作流,但实际上它可以做 。 Envoy 任何事情 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。如果我们分解这个过程,它将是这样的: 更新服务器 安装 Nginx 配置 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 第二个任务 将在我们的服务器上安装 Nginx: install-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 现在,我们可以转到第三个任务 。 就我而言,我正在部署一个 Laravel 应用程序,因此我将使用 提供的 Nginx 配置文件,并进行一些调整。 如果您要部署其他应用程序,则可以将相同的概念应用于您自己的配置文件。 copy-nginx-stub docs 在我们刚刚创建的目录中,运行以下命令: 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_ip app_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 此时,您可能想知道此过程涉及的步骤。好吧,我们可以将其分为两个步骤: 生成 SSH 密钥 将公钥复制到 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 功能强大得多😛😛