logo

部署

简介

当然,Laravel Vapor 的主要功能之一是原子、零停机时间部署。与 Vapor 的许多其他功能不同,部署**只能通过 Vapor CLI 启动**。在部署过程中,Vapor 将在运行部署的本地机器上运行 vapor.yml 文件的 build 步骤。这可能是您的个人机器或持续集成平台。

启动部署

要启动部署,请从应用程序的根目录执行 deploy CLI 命令

bash
vapor deploy production

应用程序大小

AWS Lambda 对在环境中运行的应用程序的大小有严格的限制。如果您的应用程序超过此限制,您可以利用 Vapor 的基于 Docker 的部署。基于 Docker 的部署允许您打包和部署大小高达 10GB 的应用程序。

构建钩子

您可以使用 vapor.yml 文件中的 build 键为环境定义构建钩子。这些命令在运行部署的本地机器上执行,可用于准备您的应用程序进行部署。在部署过程中,您的应用程序将在 CLI 创建的临时 .vapor 目录中构建,并且所有 build 命令都将在该临时目录中运行

yaml
id: 3
name: vapor-app
environments:
  production:
    memory: 1024
    database: vapor-app
    cache: vapor-cache
    build:
      - 'composer install --no-dev'
      - 'php artisan event:cache'
    deploy:
      - 'php artisan migrate --force'

部署钩子

您可以使用 vapor.yml 文件中的 deploy 键为环境定义部署钩子。这些命令针对已部署的环境执行,**在它被激活以供普遍使用之前**。如果这些命令中的任何一个失败,部署将不会被激活。

yaml
id: 3
name: vapor-app
environments:
  production:
    memory: 1024
    database: vapor-app
    cache: vapor-cache
    build:
      - 'composer install --no-dev'
      - 'php artisan event:cache'
    deploy:
      - 'php artisan migrate --force'

查看输出/日志

当部署钩子失败时,您可以通过 Vapor UI 的部署详情页面查看输出/日志。

此外,如果您使用 vapor deploy 命令部署应用程序,CLI 输出将包含失败的钩子输出。当然,您可以随时使用 hook:output 命令查看输出。

bash
vapor hook:output {DEPLOYMENT_HOOK_ID}

您可以使用 hook:log 命令查看与失败的钩子相关的日志。

bash
vapor hook:log {DEPLOYMENT_HOOK_ID}

压缩数据库迁移

原生 Vapor 运行时 不支持 压缩迁移。如果您想使用 Laravel 的此功能,您可以利用 Vapor 的 基于 Docker 的部署

资产

在部署过程中,Vapor 会自动提取 Laravel 项目 public 目录中的所有资产并将其上传到 S3。此外,Vapor 会创建一个 AWS CloudFront (CDN) 分发,以便高效地将这些资产分发到全球各地。

由于所有资产都将通过 S3/CloudFront 提供服务,因此您应该始终使用 Laravel 的 asset 助手生成这些资产的 URL。Vapor 会注入一个 ASSET_URL 环境变量,Laravel 的 asset 助手将在构建 URL 时使用该变量。

php
<img src="{{ asset('img.jpg') }}">

在后续部署中,只有更改的资产才会上传到 S3,而未更改的资产将从之前的部署中复制过来。

自定义资产域名

如果您想使用自己的域名来提供资产服务,您可以通过将自定义资产域名附加到项目来实现。首先,您应该 确保域名的 DNS 区域存在,并且 证书已在 us-east-1 区域中为该域名颁发

接下来,将 vapor.yml 文件的 asset-domain 选项设置为您选择的域名。

yml
id: 3
name: vapor-app
asset-domain: assets.laravel.rocks
environments:
  production:
    ...

在您项目关联的任何环境的后续部署过程中,Vapor 会将自定义域名作为别名添加到您的 CloudFront 分发。Vapor 还会注入 资产助手 和 Vite 资产编译过程的相关环境变量,以确保您的资产从您的自定义资产域名提供服务。

从 JavaScript 中引用资产

如果您在 JavaScript 代码中引用项目的公共资产,您可以使用 Vapor 的 NPM 包生成这些资产的 URL。该包包含一个 Vapor.asset 助手,它将像 Laravel 的 asset 助手一样工作,但在客户端上。要开始使用,请安装 laravel-vapor NPM 包。

bash
npm install --save-dev laravel-vapor

接下来,在应用程序的 app.js 文件中,初始化全局 Vapor JavaScript 对象。

js
// Vite
import Vapor from 'laravel-vapor'
window.Vapor = Vapor

// Mix
window.Vapor = require('laravel-vapor');

最后,您可以在 JavaScript 代码中调用 Vapor.asset 助手

js
$('#container').prepend($('<img>', { src: Vapor.asset('avatar.png') }))

或者,如果您使用的是 Vue,您可能会发现将以下 mixin 添加到您的 Vue 应用程序中很方便

Vue.mixin({
    methods: {
        asset: window.Vapor.asset
    },
});

// Within your Vue components...
<img :src="asset('img/global/logo.svg')"/>

Vapor 与 Laravel Vite

如果您在项目中使用 Laravel Vite,您只需要在引用不想捆绑的资产时使用 asset 助手,例如那些已经存在于您的公共目录中的资产。

如果您想在 Vite 项目中使用 asset 助手,您还需要在应用程序的入口点指定资产的基 URL,例如在您的 resources/js/app.js 中,如下所示:Vapor.withBaseAssetUrl(import.meta.env.VITE_VAPOR_ASSET_URL)

资产编译

如果您在 vapor.yml 配置文件列出的构建步骤之一中编译应用程序的资产,您可能需要您的构建脚本能够访问您的环境变量。一个很好的例子是实例化一个前端 SDK,例如 Pusher。

构建步骤在启动部署的环境中执行 - 通常,这将是您的本地机器或您的 CI 管道。因此,您必须确保该环境中存在所需的環境變數。

为了帮助您,Vapor 将首先尝试从 .env.[environment](例如 .env.staging)加载变量。如果该文件不存在,Vapor 将尝试从 .env 文件加载变量。您应该确保这些文件之一包含该环境的构建脚本所需的所有环境变量。

使用 CI 平台时,您可能无法访问环境文件,因为这些文件通常从版本控制中省略。在这种情况下,您的 CI 提供商通常会提供一种将变量注入构建管道的机制。例如,使用 GitHub Actions,您的 GitHub Action 配置可能如下所示

yml
- name: Deploy Environment
    run: vapor deploy production
    env:
      VITE_PUSHER_APP_KEY: ${{ secrets.VITE_PUSHER_APP_KEY }}

Vapor 与 Laravel Vite

使用 Vite 并运行 npm run build 时,Vite 将始终使用 .env.production 文件(如果存在),即使您正在部署不同的环境。如果您在部署环境中维护多个环境文件,您应该显式设置 Vite 构建模式

shell
npm run build -- --mode staging

代码拆分/动态导入与 Mix

如果您通过 Laravel Mix 利用项目中的 JavaScript 动态导入和代码拆分,您需要让 Webpack 知道每个部署的子块将从哪里加载。为了实现这一点,您可以利用 Laravel Vapor 在构建步骤期间注入到您的环境中的 ASSET_URL 变量

javascript
const mix = require("laravel-mix");

/*
 |--------------------------------------------------------------------------
 | Mix Asset Management
 |--------------------------------------------------------------------------
 |
 | Mix provides a clean, fluent API for defining some Webpack build steps
 | for your Laravel application. By default, we are compiling the Sass
 | file for the application as well as bundling up all the JS files.
 |
 */

mix
    .js("resources/js/app.js", "public/js")
    .sass("resources/sass/app.scss", "public/css");

if (mix.inProduction()) {
    const ASSET_URL = process.env.ASSET_URL + "/";

    mix.webpackConfig(webpack => {
        return {
            plugins: [
                new webpack.DefinePlugin({
                    "process.env.ASSET_PATH": JSON.stringify(ASSET_URL)
                })
            ],
            output: {
                publicPath: ASSET_URL
            }
        };
    });
}

热模块替换与 Mix

如果您在本地开发过程中使用代码分割和“热模块替换”与 Laravel Mix,则需要在本地使用 mix 助手,并在部署到 Vapor 时使用 asset 助手。

php
@if (app()->environment('local'))
    <link href="{{ mix('css/admin/app.css') }}" rel="stylesheet">
    <script src="{{ mix('js/admin/app.js') }}"></script>
@else
    <link href="{{ asset('css/admin/app.css') }}" rel="stylesheet">
    <script src="{{ asset('js/admin/app.js') }}" defer></script>
@endif

CSS 中的 URL

有时,您的 CSS 可能需要引用资产 URL,例如 background-image 属性通过 URL 引用图像。显然,您无法在 CSS 中使用 PHP 的 asset 助手。为此,Vapor 会在构建过程中自动将正确的资产基本 URL 添加到 CSS 中的所有相对 URL 前缀。在您的构建步骤执行后,Vapor 会对应用程序 public 目录中的所有 CSS 文件(包括 public 下的嵌套目录)执行此操作。

根域资产

某些应用程序(例如 PWA)可能需要从根域提供某些资产。如果您的应用程序有此需求,您可以在 vapor 配置文件中的 serve_assets 配置选项中定义一个应该从应用程序根域提供的资产数组。

php
/*
|--------------------------------------------------------------------------
| Servable Assets
|--------------------------------------------------------------------------
|
| Here you can configure list of public assets that should be servable
| from your application's domain instead of only being servable via
| the public S3 "asset" bucket or the AWS CloudFront CDN network.
|
*/

'serve_assets' => [
    'serviceWorker.js',
],

如果您的应用程序不包含 vapor 配置文件,您可以使用 vendor:publish Artisan 命令发布它。

php artisan vendor:publish --tag=vapor-config

性能损失

由于 Vapor 提供的应用程序的无服务器性质,从根域提供的资产在客户端不可缓存,并且它们使用 Laravel 路由提供。因此,您应该只提供绝对必须从根域提供的资产,因为这样做会带来轻微的性能损失。

点文件作为资产

通常,Vapor 不会将“点”文件上传到 AWS CloudFront CDN。但是,如果您需要将公共目录的点文件作为资产上传,您应该在 vapor.yml 文件中将 dot-files-as-assets 键设置为 true

yml
id: 1
name: app-test
dot-files-as-assets: true

您也可以选择从应用程序的根域提供资产点文件。

php
'serve_assets' => [
    'serviceWorker.js',
    '.well-known/assetlinks.json',
],

重新部署

有时您可能只需要重新部署给定环境而无需重建它。例如,您可能希望在更新环境变量后执行此操作。要实现这一点,您可以使用 Vapor UI 或 redeploy CLI 命令。

bash
vapor redeploy production

回滚

要回滚到之前的部署,您可以在 Vapor UI 中选择部署并点击“回滚到”按钮,或者使用 rollback CLI 命令。rollback 命令的“--select”选项将允许您从最近部署列表中选择要回滚到的部署。如果在没有此选项的情况下执行 rollback 命令,它将简单地回滚到之前最成功的部署。

bash
vapor rollback production

vapor rollback production --select

变量、密钥和回滚

当回滚到之前的部署时,Vapor 将使用环境的变量和密钥,这些变量和密钥在您回滚到的部署最初部署时存在。

从 CI 部署

到目前为止,我们已经讨论了从本地命令行部署 Vapor 项目。但是,您也可以从您选择的 CI 平台部署它们。由于 Vapor CLI 客户端是您的 Composer 依赖项的一部分,您只需在 CI 平台的部署管道中执行 vapor deploy 命令即可。

为了从您的 CI 平台验证 Vapor,您需要在您的 CI 构建环境中添加一个 VAPOR_API_TOKEN 环境变量。您可以在您的 Vapor API 设置仪表板 中生成 API 令牌。

Git 提交信息

一些 CI 平台在您的构建过程中将 Git 提交信息作为环境变量公开。您可以将此信息传递给 vapor deploy 命令。例如,如果使用 CodeShip

sh
vapor deploy production --commit="${CI_COMMIT_ID}" --message="${CI_MESSAGE}"

提交哈希将被注入到您的应用程序的环境变量中,作为 VAPOR_COMMIT_HASH

使用 GitHub Actions 的示例

如果您的应用程序使用 GitHub Actions 作为其 CI 平台,以下指南将帮助您配置 Vapor 部署,以便在有人将提交推送到 master 分支时自动部署您的应用程序。

  1. 首先,将 VAPOR_API_TOKEN 环境变量添加到您的“GitHub > 项目设置 > 密钥”设置中,以便 GitHub 在运行操作时可以验证 Vapor。

  2. 接下来,在 your-project/.github/workflows 目录中创建一个 deploy.yml 文件。该文件应包含以下内容

yml
name: Deploy

on:
  push:
    branches: [ master ]

jobs:
  deploy:
    runs-on: ubuntu-latest
    steps:
      - name: Checkout code
        uses: actions/checkout@v4
      - name: Setup PHP
        uses: shivammathur/setup-php@v2
        with:
          php-version: 8.0
          tools: composer:v2
          coverage: none
      - name: Require Vapor CLI
        run: composer global require laravel/vapor-cli
      - name: Install Project Dependencies
        run: composer install --no-interaction --prefer-dist --optimize-autoloader
      - name: Deploy Environment
        run: vapor deploy
        env:
          VAPOR_API_TOKEN: ${{ secrets.VAPOR_API_TOKEN }}
  1. 最后,您可以编辑 deploy.yml 文件以适应您的应用程序的部署需求,因为它可能需要不同的 PHP 版本或像 npm 这样的库。完成后,将 deploy.yml 文件提交并推送到 master,以便 GitHub Actions 可以运行第一个部署作业。

Docker Arm 运行时

由于 GitHub 操作在 x86_64 架构上运行,因此它们无法原生编译基于 arm64 的镜像。为了编译 docker-arm 运行时,可以使用 QEMU 模拟 arm64 平台。要开始,请在您的 deploy.yml 中添加以下内容,紧接在“签出代码”步骤之后

yml
- name: Setup QEMU
  uses: docker/setup-qemu-action@v2
  with:
    platforms: arm64

使用 Chipper CI 的示例

如果您的应用程序使用 Chipper CI 作为其 CI 平台,以下指南将帮助您配置 Vapor 部署,以便您的应用程序在有人将提交推送到 master 分支时自动部署。

  1. 首先,将 VAPOR_API_TOKEN 环境变量添加到您的“Chipper CI > 项目设置 > 项目环境变量”设置中,以便 Chipper CI 在运行您的构建管道时可以与 Vapor 进行身份验证。

  2. 然后,在“构建管道”仪表板上,添加一个名为 Deploy 的步骤,并使用以下内容

bash
if [[ $CI_COMMIT_BRANCH == 'master' ]]; then
    composer install --no-interaction --prefer-dist --optimize-autoloader

    composer global require laravel/vapor-cli

    vapor deploy
fi
  1. 接下来,将任何更改提交并推送到 master 分支,以便 Chipper CI 部署您的应用程序。

基于 Docker 的运行时

如果您计划使用基于 Docker 的运行时来运行您的 Vapor 应用程序,您必须购买 Chipper CI 付费计划并在包含基于 Docker 的 Vapor 应用程序的每个项目中启用 Docker。