支持Laravel.io的持续开发 →

Laravel Envoy - 自动化繁琐事物

2024年2月17日 阅读时间:8分钟

Laravel Envoy

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

我认为 Envoy 被低估了,尽管我一直觉得它非常实用,但我很少看到它被使用。在这篇文章中,我们将探讨 Envoy 如何帮助你提高生产力🚀。

Laravel Envoy 不仅针对 Laravel 开发者,也不仅限于 Laravel 项目,任何人都可以使用它 ❤️。

首先,让我们讨论 Envoy 中的两个关键概念

  1. 任务:代表特定的动作,如更新服务器或克隆存储库。
  2. 故事:是任务的集合。

现在你需要知道的就这些,你总是可以阅读关于所有功能的文档(链接)

我们在自动化什么?

在这篇文章中,我们将自动化开发者在部署应用程序时通常会做的两件事

  1. 配置Nginx。
  2. 生成SSH密钥并将它们添加到GitHub,以便能够访问私有仓库。

是的,我知道,大多数时候 Envoy 用于CI/CD工作流程,但它在实际上可以做到 一切,真的是这样。

Envoy的设置

首先创建一个目录

mkdir tuto && cd $_ 

$ take tuto 如果你使用的是 zsh

通过运行以下命令安装 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 做的,把每一步想象成一个 任务,整个过程想象成一个 故事

所以,让我们把刚刚说的转换成一个故事

@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 应用程序,所以我将使用由 文档 提供的 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,所以在我们开始之前,您需要 创建一个 token

在创建您的 token 时,确保您只选择 "admin:public_key" 范围。

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

@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 😛😛

最后更新 5 个月前。

用户driesvints喜欢这篇文章

1
喜欢这篇文章吗? 告诉作者,并给他们一个点赞!
oussamamater (Oussama Mater) 我是一名软件工程师和CTF玩家。我使用Laravel和Vue.js将想法转化为应用程序 🚀

你可能还喜欢这些文章

2024年3月11日

如何使用Larastan将你的Laravel应用程序从0到9进行优化

在应用程序执行之前发现Laravel应用程序中的错误是可能的,多亏了Larastan,它是...

阅读文章
2024年7月19日

无特质标准化的API响应

我发现大多数用于API响应的库都是使用特性实现的,并且...

阅读文章
2024年7月17日

在您的Laravel项目中通过Discord通知收集反馈

如何在Laravel项目中创建一个反馈模块,并在收到消息时收到Discord通知...

阅读文章

我们要感谢这些 惊人的公司 对我们的支持

您的标志在这里吗?

Laravel.io

Laravel 的问题解决、知识分享和社区建设平台。

版权所有 © 2024 Laravel.io - 保留所有权利。