Laravel Octane 完整指南:服务器部署、常驻进程与状态管理

原作者:Laravel 文档贡献者;版权归 Taylor Otwell,文档采用 MIT 许可证。中文翻译、示意图与技术审校:未完纪。 原文:Laravel Octane — Laravel 13.x Documentation。本文完整翻译 Laravel 13.x 的 Octane 文档,读取日期2026年10月5日。适用边界为Laravel 13.x、PHP 8.3及以上;服务器二进制、扩展及系统要求还应与实际选择的版本匹配。代码均来自官方文档并完整保留,编辑补充与反例提示已明确标出。本次未运行源文命令。

Octane worker只启动应用一次并复用处理多个请求,当前请求数据与Swoole共享缓存的生命周期示意图
图1:Octane 的常驻应用、请求数据与共享存储边界。未完纪原创技术示意图;不是性能测试图。

简介

Laravel Octane 使用高性能应用服务器来运行 Laravel 应用,包括 FrankenPHP、Open Swoole、Swoole 和 RoadRunner,从而提升应用性能。Octane 只启动应用一次,将其保留在内存中,再持续向它分发请求,减少重复启动应用的开销。

安装

可以通过 Composer 包管理器安装 Octane:

composer require laravel/octane

安装后,运行 Artisan 命令 octane:install,将 Octane 配置文件安装到应用中:

php artisan octane:install

服务器前提条件

FrankenPHP

FrankenPHP 是使用 Go 编写的 PHP 应用服务器,支持 Early Hints、Brotli 和 Zstandard 压缩等现代 Web 特性。安装 Octane 时如果选择 FrankenPHP 作为服务器,Octane 会自动为你下载并安装 FrankenPHP 二进制文件。

通过 Laravel Sail 使用 FrankenPHP

如果准备使用 Laravel Sail 开发应用,应运行以下命令来安装 Octane 和 FrankenPHP:

./vendor/bin/sail up

./vendor/bin/sail composer require laravel/octane

接着,使用 octane:install Artisan 命令安装 FrankenPHP 二进制文件:

./vendor/bin/sail artisan octane:install --server=frankenphp

最后,在应用的 docker-compose.yml 中,为 laravel.test 服务添加 SUPERVISOR_PHP_COMMAND 环境变量。这个变量包含 Sail 启动应用所使用的命令,让它通过 Octane 提供服务,而不是使用 PHP 开发服务器:

services:
  laravel.test:
    environment:
      SUPERVISOR_PHP_COMMAND: "/usr/bin/php -d variables_order=EGPCS /var/www/html/artisan octane:start --server=frankenphp --host=0.0.0.0 --admin-port=2019 --port='${APP_PORT:-80}'"
      XDG_CONFIG_HOME:  /var/www/html/config
      XDG_DATA_HOME:  /var/www/html/data

要启用 HTTPS、HTTP/2 和 HTTP/3,则采用下面这些改动:

services:
  laravel.test:
    ports:
        - '${APP_PORT:-80}:80'
        - '${VITE_PORT:-5173}:${VITE_PORT:-5173}'
        - '443:443'
        - '443:443/udp'
    environment:
      SUPERVISOR_PHP_COMMAND: "/usr/bin/php -d variables_order=EGPCS /var/www/html/artisan octane:start --host=localhost --port=443 --admin-port=2019 --https"
      XDG_CONFIG_HOME:  /var/www/html/config
      XDG_DATA_HOME:  /var/www/html/data

通常应通过 https://localhost 访问使用 FrankenPHP 的 Sail 应用;使用 https://127.0.0.1 需要额外配置,官方不建议这样做。

通过 Docker 使用 FrankenPHP

FrankenPHP 的官方 Docker 镜像可以带来性能上的改善,并允许使用静态安装版本中未包含的额外扩展。官方镜像还支持在 FrankenPHP 不原生支持的平台上运行,例如 Windows。它们可用于本地开发,也可用于生产环境。

可以从下面这个 Dockerfile 开始,将使用 FrankenPHP 的 Laravel 应用容器化:

FROM dunglas/frankenphp

RUN install-php-extensions \
    pcntl
    # Add other PHP extensions here...

COPY . /app

ENTRYPOINT ["php", "artisan", "octane:frankenphp"]

编辑说明:这是容器化起点,不是完整生产Dockerfile。原文没有固定 dunglas/frankenphp 的标签或摘要,也未展示Composer依赖、前端资源和应用所需其他PHP扩展的构建过程。部署前需按实际项目补齐,并通过 .dockerignore 排除 .env、私钥等不应进入镜像的文件。

然后,在开发期间,可以使用下面的 Docker Compose 文件运行应用:

# compose.yaml
services:
  frankenphp:
    build:
      context: .
    entrypoint: php artisan octane:frankenphp --workers=1 --max-requests=1
    ports:
      - "8000:8000"
    volumes:
      - .:/app

编辑说明:上面的绑定挂载、单worker和每个请求后重启的组合明确用于开发。不要照搬成生产容量配置。后续Sail示例也属于开发环境;0.0.0.0 会监听全部接口,宿主机端口映射、FrankenPHP管理端口2019和RoadRunner RPC端口6001都应按实际网络边界保护。

如果向 php artisan octane:start 显式传入 --log-level 选项,Octane 会使用 FrankenPHP 的原生日志记录器;若没有另外配置,它会输出结构化 JSON 日志。

有关通过 Docker 运行 FrankenPHP 的更多信息,请参阅 FrankenPHP 官方文档。

自定义 Caddyfile 配置

使用 FrankenPHP 时,可以在启动 Octane 时通过 --caddyfile 选项指定自定义 Caddyfile:

php artisan octane:start --server=frankenphp --caddyfile=/path/to/your/Caddyfile

这样就能在默认设置之外定制 FrankenPHP,例如加入自定义中间件、配置高级路由或添加自定义指令。Caddyfile 的语法和配置选项,可参阅 Caddy 官方文档。

RoadRunner

RoadRunner 由使用 Go 构建的 RoadRunner 二进制程序驱动。首次启动基于 RoadRunner 的 Octane 服务器时,Octane 会提示为你下载并安装该二进制程序。

通过 Laravel Sail 使用 RoadRunner

如果准备使用 Laravel Sail 开发应用,应执行以下命令安装 Octane 和 RoadRunner:

./vendor/bin/sail up

./vendor/bin/sail composer require laravel/octane spiral/roadrunner-cli spiral/roadrunner-http

接着进入 Sail shell,使用 rr 可执行程序获取最新的 Linux 版 RoadRunner 二进制文件:

./vendor/bin/sail shell

# Within the Sail shell...
./vendor/bin/rr get-binary

然后,在应用的 docker-compose.yml 中,为 laravel.test 服务添加 SUPERVISOR_PHP_COMMAND 环境变量。它告诉 Sail 用哪个命令通过 Octane 提供应用服务,替代 PHP 开发服务器:

services:
  laravel.test:
    environment:
      SUPERVISOR_PHP_COMMAND: "/usr/bin/php -d variables_order=EGPCS /var/www/html/artisan octane:start --server=roadrunner --host=0.0.0.0 --rpc-port=6001 --port='${APP_PORT:-80}'"

最后,确保 rr 二进制文件具有执行权限,再构建 Sail 镜像:

chmod +x ./rr

./vendor/bin/sail build --no-cache

Swoole

如果准备使用 Swoole 应用服务器运行 Laravel Octane 应用,必须安装 Swoole PHP 扩展。通常可以通过 PECL 安装:

pecl install swoole

Open Swoole

如果准备使用 Open Swoole 应用服务器运行 Laravel Octane 应用,必须安装 Open Swoole PHP 扩展。通常可以通过 PECL 安装:

pecl install openswoole

Laravel Octane 配合 Open Swoole 使用时,可以获得与 Swoole 相同的相关功能,例如并发任务、tick 和时间间隔任务。

通过 Laravel Sail 使用 Swoole

通过 Sail 运行 Octane 应用之前,请确保使用最新版 Laravel Sail,并在应用根目录执行 ./vendor/bin/sail build --no-cache。

也可以使用 Laravel 官方的 Docker 开发环境 Laravel Sail,开发基于 Swoole 的 Octane 应用。Sail 默认包含 Swoole 扩展,但仍然需要调整它使用的 docker-compose.yml 文件。

首先,在 docker-compose.yml 的 laravel.test 服务定义中添加 SUPERVISOR_PHP_COMMAND 环境变量。它包含 Sail 用于通过 Octane 提供应用服务的命令,替代 PHP 开发服务器:

services:
  laravel.test:
    environment:
      SUPERVISOR_PHP_COMMAND: "/usr/bin/php -d variables_order=EGPCS /var/www/html/artisan octane:start --server=swoole --host=0.0.0.0 --port='${APP_PORT:-80}'"

最后构建 Sail 镜像:

./vendor/bin/sail build --no-cache

Swoole 配置

Swoole 支持一些额外配置项,需要时可以加到应用的 octane 配置文件中。这些选项通常不需要修改,因此没有包含在默认配置文件里:

'swoole' => [
    'options' => [
        'log_file' => storage_path('logs/swoole_http.log'),
        'package_max_length' => 10 * 1024 * 1024,
    ],
],

运行应用

通过 octane:start Artisan 命令启动 Octane 服务器。默认情况下,它会使用应用 octane 配置文件的 server 选项所指定的服务器:

php artisan octane:start

Octane 默认在8000端口启动服务器,因此可以在浏览器中通过 http://localhost:8000 访问应用。

在生产环境中保持 Octane 运行

把 Octane 应用部署到生产环境时,应使用 Supervisor 等进程监控工具,确保 Octane 服务器持续运行。下面是一份 Supervisor 配置示例:

[program:octane]
process_name=%(program_name)s_%(process_num)02d
command=php /home/forge/example.com/artisan octane:start --server=frankenphp --host=127.0.0.1 --port=8000
autostart=true
autorestart=true
user=forge
redirect_stderr=true
stdout_logfile=/home/forge/example.com/storage/logs/octane.log
stopwaitsecs=3600

通过 HTTPS 提供应用服务

默认情况下,通过 Octane 运行的应用会生成以 http:// 开头的链接。如果通过 HTTPS 提供服务,可以将应用 config/octane.php 使用的 OCTANE_HTTPS 环境变量设为 true。开启后,Octane 会告诉 Laravel,为所有生成的链接使用 https:// 前缀:

'https' => env('OCTANE_HTTPS', false),

编辑说明:OCTANE_HTTPS=true 影响Laravel生成的URL,不会自行申请证书或给所有部署自动配置TLS。需由FrankenPHP或前置代理实际终止TLS。

通过 Nginx 提供应用服务

如果你尚未准备好自己管理服务器配置,或不熟悉运行可靠的 Laravel Octane 应用所需的各种服务,可以了解 Laravel Cloud,它提供完全托管的 Laravel Octane 支持。

在生产环境中,应将 Octane 放在 Nginx 或 Apache 这类传统 Web 服务器后面。这样可以由 Web 服务器直接提供图片、样式表等静态资源,并处理 SSL/TLS 证书终止。

在下面的 Nginx 配置中,Nginx 负责站点静态资源,并将其他请求代理到运行在8000端口的 Octane 服务器:

map $http_upgrade $connection_upgrade {
    default upgrade;
    ''      close;
}

server {
    listen 80;
    listen [::]:80;
    server_name domain.com;
    server_tokens off;
    root /home/forge/domain.com/public;

    index index.php;

    charset utf-8;

    location /index.php {
        try_files /not_exists @octane;
    }

    location / {
        try_files $uri $uri/ @octane;
    }

    location = /favicon.ico { access_log off; log_not_found off; }
    location = /robots.txt  { access_log off; log_not_found off; }

    access_log off;
    error_log  /var/log/nginx/domain.com-error.log error;

    error_page 404 /index.php;

    location @octane {
        set $suffix "";

        if ($uri = /index.php) {
            set $suffix ?$query_string;
        }

        proxy_http_version 1.1;
        proxy_set_header Host $http_host;
        proxy_set_header Scheme $scheme;
        proxy_set_header SERVER_PORT $server_port;
        proxy_set_header REMOTE_ADDR $remote_addr;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_set_header Upgrade $http_upgrade;
        proxy_set_header Connection $connection_upgrade;

        proxy_pass http://127.0.0.1:8000$suffix;
    }
}

编辑说明:该Nginx示例只监听80端口,没有配置HTTPS监听器与证书。生产使用时应替换域名、根目录与日志路径,补齐实际TLS配置,并让后端Octane仅能被预期代理访问。原文配置关闭了access log,是否这样做应结合排障与审计需求决定。

监听文件变更

Octane 服务器启动时只把应用加载到内存一次,因此修改应用文件之后,仅刷新浏览器不会反映这些变化。例如,在 routes/web.php 中新增路由,必须重启服务器才能生效。为了方便开发,可以使用 --watch 标志,让 Octane 在应用文件发生变化时自动重启服务器:

php artisan octane:start --watch

使用这一功能前,要确保本地开发环境安装了 Node,并在项目中安装 Chokidar 文件监听库:

npm install --save-dev chokidar

可以在 config/octane.php 的 watch 配置项中指定需要监听的目录和文件。

指定 worker 数量

默认情况下,Octane 会为机器提供的每个 CPU 核心启动一个应用请求 worker,这些 worker 负责处理进入应用的 HTTP 请求。可以在调用 octane:start 时使用 --workers 选项手动指定启动数量:

php artisan octane:start --workers=4

使用 Swoole 应用服务器时,还可以指定要启动多少个 task worker:

php artisan octane:start --workers=4 --task-workers=6

指定最大请求数

为了缓解偶发内存泄漏的影响,Octane 会在一个 worker 处理500个请求后,优雅地重启它。可以通过 --max-requests 调整这一数量:

php artisan octane:start --max-requests=250

指定最长执行时间

默认情况下,Laravel Octane 通过 config/octane.php 中的 max_execution_time 选项,将传入请求的最长执行时间设为30秒:

'max_execution_time' => 30,

该值表示请求被终止之前允许执行的最长秒数。设为0会完全取消执行时间限制。对于处理文件上传、数据处理或外部服务 API 调用等长耗时请求的应用,这个配置尤其有用。

修改 max_execution_time 后,必须重启 Octane 服务器,配置才会生效。

重新加载 worker

可以使用 octane:reload 命令,优雅地重启 Octane 服务器中的应用 worker。通常应在部署之后运行,让新代码被加载到内存中,并用于处理后续请求:

php artisan octane:reload

停止服务器

可以使用 octane:stop Artisan 命令停止 Octane 服务器:

php artisan octane:stop

检查服务器状态

可以使用 octane:status Artisan 命令检查 Octane 服务器的当前状态:

php artisan octane:status

依赖注入与 Octane

Octane 只启动应用一次,并在处理请求时一直将应用留在内存中,因此构建应用时有一些注意事项。例如,服务提供者的 register 和 boot 方法,只会在请求 worker 最初启动时执行一次;后续请求会复用同一个应用实例。

因此,把应用服务容器或请求对象注入任何对象的构造方法时,都要格外留意。这样做可能让该对象在后续请求中仍持有已经过时的容器或请求。

Octane 会自动在请求之间重置框架自身的状态,但它并不总能知道,如何重置由你的应用创建的全局状态。因此,应用需要按适合 Octane 的方式设计。下面介绍最常见的几类问题。

注入容器

一般应避免把应用服务容器或 HTTP 请求实例注入其他对象的构造方法。例如,下面这个绑定将整个应用容器注入到一个以单例方式注册的对象中。这是需要留意的反例:

use App\Service;
use Illuminate\Contracts\Foundation\Application;

/**
 * Register any application services.
 */
public function register(): void
{
    $this->app->singleton(Service::class, function (Application $app) {
        return new Service($app);
    });
}

在这个例子中,如果 Service 实例在应用启动阶段被解析,容器就会被注入其中,后续请求中该 Service 仍然持有同一个容器。对某些应用,这不一定构成问题;但如果某些绑定是在启动流程的后续阶段或后来的请求中加入的,该容器可能意外地缺少这些绑定。

解决办法可以是不再将它注册为单例,或者给服务注入一个用于解析容器的闭包,让它总能取得当前容器实例。下面两种绑定是替代方案,应按需求选择一种:

use App\Service;
use Illuminate\Container\Container;
use Illuminate\Contracts\Foundation\Application;

$this->app->bind(Service::class, function (Application $app) {
    return new Service($app);
});

$this->app->singleton(Service::class, function () {
    return new Service(fn () => Container::getInstance());
});

全局辅助函数 app 和 Container::getInstance() 方法,始终返回当前版本的应用容器。

注入请求

一般应避免把应用服务容器或 HTTP 请求实例注入其他对象的构造方法。例如,下面的绑定将整个请求实例注入到一个以单例方式注册的对象中。这同样是需要留意的反例:

use App\Service;
use Illuminate\Contracts\Foundation\Application;

/**
 * Register any application services.
 */
public function register(): void
{
    $this->app->singleton(Service::class, function (Application $app) {
        return new Service($app['request']);
    });
}

在这个例子中,如果 Service 在应用启动过程中被解析,HTTP 请求就会被注入服务,后续请求中它仍持有同一个请求。于是,其中的请求头、输入、查询字符串及其他请求数据,都会变成错误的旧数据。

解决办法可以是不再将绑定注册为单例,也可以给服务注入一个请求解析闭包,使其取得当前请求。更推荐的方式是,在运行时直接把对象所需的具体请求信息,传给对象的某个方法。下面各段是不同的可选方案:

use App\Service;
use Illuminate\Contracts\Foundation\Application;

$this->app->bind(Service::class, function (Application $app) {
    return new Service($app['request']);
});

$this->app->singleton(Service::class, function (Application $app) {
    return new Service(fn () => $app['request']);
});

// Or...

$service->method($request->input('name'));

编辑说明:这些绑定是互相替代的示例,不应全部顺序注册到同一服务,否则后面的绑定会覆盖前面的绑定。原文闭包示例捕获了 $app;若代码自身长期保存旧容器,仍需检查其生命周期。通常优先采用原文更推荐的方法参数方案,或在真正使用时通过 request() 取得当前请求,而不要提前解析并保存请求实例。

全局 request 辅助函数始终返回应用当前正在处理的请求,因此可以在应用中使用。

在控制器方法和路由闭包的参数上,为 Illuminate\Http\Request 添加类型声明是可以的。

注入配置仓库

一般应避免将配置仓库实例注入其他对象的构造方法。例如,下面的绑定将配置仓库注入一个以单例方式注册的对象中:

use App\Service;
use Illuminate\Contracts\Foundation\Application;

/**
 * Register any application services.
 */
public function register(): void
{
    $this->app->singleton(Service::class, function (Application $app) {
        return new Service($app->make('config'));
    });
}

在这个例子中,如果配置值在请求之间发生变化,该服务无法取得新值,因为它依赖的仍是最初那个配置仓库实例。

解决办法可以是不再把绑定注册为单例,或者给类注入一个用于解析配置仓库的闭包。下面是两种可选方案:

use App\Service;
use Illuminate\Container\Container;
use Illuminate\Contracts\Foundation\Application;

$this->app->bind(Service::class, function (Application $app) {
    return new Service($app->make('config'));
});

$this->app->singleton(Service::class, function () {
    return new Service(fn () => Container::getInstance()->make('config'));
});

全局 config 辅助函数始终返回最新的配置仓库及相应配置,因此可以在应用中使用。

管理内存泄漏

记住,Octane 会在请求之间把应用保留在内存中。因此,不断往静态数组中添加数据会导致内存持续增长。例如,下面的控制器存在内存泄漏:应用每收到一次请求,都会继续向静态 $data 数组添加数据。这是用于说明问题的反例:

use App\Service;
use Illuminate\Http\Request;
use Illuminate\Support\Str;

/**
 * Handle an incoming request.
 */
public function index(Request $request): array
{
    Service::$data[] = Str::random(10);

    return [
        // ...
    ];
}

构建应用时,要特别注意避免这类内存泄漏。建议在本地开发期间监控应用的内存使用量,确保没有引入新的泄漏。

并发任务

这一功能需要 Swoole。

使用 Swoole 时,可以通过轻量的后台任务并发执行操作,具体使用 Octane 的 concurrently 方法。配合 PHP 数组解构,就可以取得每项操作的结果:

use App\Models\User;
use App\Models\Server;
use Laravel\Octane\Facades\Octane;

[$users, $servers] = Octane::concurrently([
    fn () => User::all(),
    fn () => Server::all(),
]);

Octane 的并发任务使用 Swoole 的 task worker,在与传入请求完全不同的进程中执行。可用于处理并发任务的 worker 数量,由 octane:start 的 --task-workers 选项决定:

php artisan octane:start --workers=4 --task-workers=6

受 Swoole 任务系统的限制,调用 concurrently 方法时,不应传入超过1024个任务。

Tick 与时间间隔任务

这一功能需要 Swoole。

使用 Swoole 时,可以注册每隔指定秒数执行一次的 tick 操作。通过 tick 方法注册回调:第一个参数是标识 ticker 名称的字符串,第二个参数是按指定间隔调用的可调用对象。

下面注册一个每10秒调用一次的闭包。通常应在应用某个服务提供者的 boot 方法中调用 tick:

Octane::tick('simple-ticker', fn () => ray('Ticking...'))
    ->seconds(10);

编辑说明:ray() 来自额外的调试工具,并不是所有Laravel项目默认提供的函数。此示例保留原文;若项目没有安装相应工具,可改用应用已有日志方式,例如 logger()->debug('Ticking...')。本次没有安装调试依赖或执行回调。

使用 immediate 方法,可以让 Octane 在服务器刚启动时立即执行 tick 回调,之后再每隔 N 秒执行一次:

Octane::tick('simple-ticker', fn () => ray('Ticking...'))
    ->seconds(10)
    ->immediate();

Octane 缓存

这一功能需要 Swoole。

使用 Swoole 时,可以使用 Octane 缓存驱动。官方文档称,它的读写速度最高可达每秒200万次操作,因此适合需要极高缓存读写吞吐量的应用。这个数字是文档给出的上限表述,并非本次翻译的测试结果。

该缓存驱动基于 Swoole tables,缓存中的全部数据对同一服务器上的所有 worker 都可见。但是,服务器重启后,缓存数据会被清空:

Cache::store('octane')->put('framework', 'Laravel', 30);

Octane 缓存允许的最大条目数,可以在应用的 octane 配置文件中定义。

按间隔刷新缓存

除 Laravel 缓存系统提供的常规方法外,Octane 缓存驱动还支持按时间间隔刷新的缓存。这些缓存会按指定间隔自动更新,应在某个服务提供者的 boot 方法中注册。例如,下列缓存每5秒刷新一次:

use Illuminate\Support\Str;

Cache::store('octane')->interval('random', function () {
    return Str::random(10);
}, seconds: 5);

Tables

这一功能需要 Swoole。

使用 Swoole 时,可以定义自己的 Swoole table,并与之交互。Swoole tables 提供很高的吞吐能力,数据可供同一服务器的全部 worker 访问。不过,服务器重启后,其中的数据会丢失。

表应定义在应用 octane 配置文件的 tables 配置数组中。系统已经提供一个最多容纳1000行的示例表。字符串列的最大长度,可以像下面这样写在列类型之后:

'tables' => [
    'example:1000' => [
        'name' => 'string:1000',
        'votes' => 'int',
    ],
],

通过 Octane::table 方法访问表:

use Laravel\Octane\Facades\Octane;

Octane::table('example')->set('uuid', [
    'name' => 'Nuno Maduro',
    'votes' => 1000,
]);

return Octane::table('example')->get('uuid');

Swoole tables 支持的列类型为 string、int 和 float。

编辑说明:版本、状态与生产运行边界

上述46个官方代码块均按源文保留。Composer、PECL、npm安装以及Octane自动下载FrankenPHP、rr get-binary 获取RoadRunner,都涉及下载并使用外部代码或二进制。原文未给出所有组件的固定版本或校验摘要;实际部署应使用经过验证的兼容版本和锁定依赖,不把文档中的“最新版”视为可复现版本。本译文没有下载或执行这些运行组件。

单例持有请求、容器或配置仓库,以及向静态数组不断追加数据的代码,都是说明问题的反例。前者可能在不同请求间串用用户输入或身份相关数据,后者会使内存持续增长。默认每500次请求重启worker,只能缓解部分累积问题,不能替代正确的生命周期设计。修改 max_execution_time 后需重启;将其设为0会取消超时,长请求仍需考虑资源上限。

User::all() 和 Server::all() 的并发示例会取回完整结果集,适合说明API;数据规模较大时,应另行评估分页、分块和内存占用。Swoole任务在不同进程中执行,不能假定共享同一个PHP对象实例。Octane缓存与tables是同机共享内存,重启后丢失;不要把它们当成持久数据库或跨服务器的一致性存储。每秒200万次读写是源文的性能表述,页面未给出足以在本次复现的基准环境。

部署时应在新代码就绪后重载worker,再按自己的应用验证请求正确性、资源使用及回退流程。本译文只完成逐段核对与静态审查,没有启动PHP服务器、Sail、Docker、Nginx或Supervisor,也没有测量性能。

MIT 许可证

以下保留 Laravel 文档仓库的版权与许可通知,来源:laravel/docs 13.x license.md。

The MIT License (MIT)

Copyright (c) Taylor Otwell

Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.

原文中的参考链接

© 版权声明
THE END
喜欢就支持一下吧
点赞0 分享
评论 抢沙发

请登录后发表评论

    暂无评论内容