简介

Laravel Sail 是一个轻量级命令行界面,用于与 Laravel 默认的 Docker 开发环境进行交互。Sail 提供了一个出色的起点,无需具备 Docker 使用经验,即可使用 PHP、MySQL 和 Redis 构建 Laravel 应用程序。

Sail 的核心是存储在项目根目录下的 compose.yaml 文件和 sail 脚本。sail 脚本提供了一个命令行界面,通过便捷的方式与 compose.yaml 文件中定义的 Docker 容器进行交互。

Laravel Sail 支持 macOS、Linux 和 Windows(通过 WSL2)。

安装与设置

您可以使用 Composer 包管理器安装 Sail:

composer require laravel/sail --dev

安装 Sail 后,您可以运行 sail:install Artisan 命令。该命令会将 Sail 的 compose.yaml 文件发布到应用程序的根目录,并修改您的 .env 文件,添加连接 Docker 服务所需的环境变量:

php artisan sail:install

最后,您可以启动 Sail。要继续了解 Sail 的使用方法,请继续阅读本文档的剩余部分:

./vendor/bin/sail up

如果您使用的是适用于 Linux 的 Docker Desktop,应通过执行以下命令来使用 default Docker 上下文:docker context use default。此外,如果在容器内遇到文件权限错误,可能需要将 SUPERVISOR_PHP_USER 环境变量设置为 root。

添加额外服务

如果您想在现有的 Sail 安装中添加额外服务,可以运行 sail:add Artisan 命令:

php artisan sail:add

使用开发容器

如果您希望在 开发容器(Devcontainer) 中进行开发,可以为 sail:install 命令提供 --devcontainer 选项。--devcontainer 选项会指示 sail:install 命令,将默认的 .devcontainer/devcontainer.json 文件发布到应用程序的根目录:

php artisan sail:install --devcontainer

重新构建 Sail 镜像

有时您可能需要完全重新构建 Sail 镜像,以确保镜像中的所有软件包和软件都保持最新。您可以通过 build 命令来实现:

docker compose down -v

sail build --no-cache

sail up

配置 Shell 别名

默认情况下,Sail 命令通过所有新 Laravel 应用程序中自带的 vendor/bin/sail 脚本来调用:

./vendor/bin/sail up

然而,与其反复输入 vendor/bin/sail 来执行 Sail 命令,您可能希望配置一个 shell 别名,以便更轻松地执行 Sail 命令:

alias sail='sh $([ -f sail ] && echo sail || echo vendor/bin/sail)'

为确保该别名始终可用,您可以将其添加到主目录下的 shell 配置文件中,例如 ~/.zshrc 或 ~/.bashrc,然后重启 shell。

配置好 shell 别名后,只需输入 sail 即可执行 Sail 命令。本文档后续的示例均假设您已配置此别名:

sail up

启动和停止 Sail

Laravel Sail 的 compose.yaml 文件定义了多种协同工作的 Docker 容器,以帮助您构建 Laravel 应用程序。这些容器中的每一个都是 compose.yaml 文件中 services 配置的一个条目。laravel.test 容器是主要的应用程序容器,负责提供您的应用程序服务。

在启动 Sail 之前,您应确保本地计算机上没有其他 Web 服务器或数据库正在运行。要启动应用程序 compose.yaml 文件中定义的所有 Docker 容器,您应执行 up 命令:

sail up

要在后台启动所有 Docker 容器,您可以以“分离(detached)”模式启动 Sail:

sail up -d

应用程序的容器启动后,您可以在浏览器中通过以下地址访问项目:http://localhost。

要停止所有容器,您只需按下 Control + C 即可停止容器的运行。或者,如果容器在后台运行,您可以使用 stop 命令:

sail stop

执行命令

使用 Laravel Sail 时,您的应用程序在 Docker 容器内运行,并与本地计算机隔离。不过,Sail 提供了一种便捷的方式,可针对您的应用程序运行各种命令,例如任意 PHP 命令、Artisan 命令、Composer 命令以及 Node / NPM 命令。

阅读 Laravel 文档时,您经常会看到对 Composer、Artisan 和 Node / NPM 命令的引用,但这些引用并未提及 Sail。这些示例默认这些工具已安装在您的本地计算机上。如果您在本地 Laravel 开发环境中使用 Sail,则应通过 Sail 执行这些命令:

# Running Artisan commands locally...
php artisan queue:work

# Running Artisan commands within Laravel Sail...
sail artisan queue:work

执行 PHP 命令

可以使用 php 命令执行 PHP 命令。当然,这些命令将使用为您的应用程序配置的 PHP 版本来执行。如需了解 Laravel Sail 可用的 PHP 版本,请参阅 PHP 版本文档:

sail php --version

sail php script.php

执行 Composer 命令

可以使用 composer 命令执行 Composer 命令。Laravel Sail 的应用程序容器中包含了 Composer 安装:

sail composer require laravel/sanctum

执行 Artisan 命令

可以使用 artisan 命令执行 Laravel Artisan 命令:

sail artisan queue:work

执行 Node / NPM 命令

可以使用 node 命令执行 Node 命令,使用 npm 命令执行 NPM 命令:

sail node --version

sail npm run dev

如果您希望,也可以使用 Yarn 而非 NPM:

sail yarn

与数据库交互

MySQL

您可能已经注意到,应用程序的 compose.yaml 文件中包含一个 MySQL 容器条目。该容器使用 Docker 卷,以确保数据库中存储的数据在停止和重启容器后依然得以保留。

此外,MySQL 容器首次启动时,会为您创建两个数据库。第一个数据库的名称取自 DB_DATABASE 环境变量的值,用于本地开发。第二个是名为 testing 的专用测试数据库,可确保测试不会干扰开发数据。

容器启动后,您可以将应用程序 .env 文件中的 DB_HOST 环境变量设置为 mysql,从而连接到应用程序内的 MySQL 实例。

要从本地计算机连接到应用程序的 MySQL 数据库,可以使用图形化数据库管理应用程序,例如 TablePlus。默认情况下,MySQL 数据库可通过 localhost 的 3306 端口访问,访问凭据与 DB_USERNAME 和 DB_PASSWORD 环境变量的值一致。或者,您也可以以 root 用户身份连接,该用户的密码同样使用 DB_PASSWORD 环境变量的值。

MongoDB

如果您在安装 Sail 时选择了安装 MongoDB 服务,应用程序的 compose.yaml 文件中就会包含一个 MongoDB Atlas Local 容器条目,该容器提供具备 搜索索引等 Atlas 功能的 MongoDB 文档数据库。此容器使用 Docker 卷,因此即使在停止和重启容器后,数据库中存储的数据也能得以保留。

容器启动后,你可以在应用的 .env 文件中将 MONGODB_URI 环境变量设置为 mongodb://mongodb:27017,从而在应用内连接到 MongoDB 实例。默认情况下身份验证处于禁用状态,不过在启动 mongodb 容器之前,你可以设置 MONGODB_USERNAME 和 MONGODB_PASSWORD 环境变量来启用身份验证。然后,将凭据添加到连接字符串中:

MONGODB_USERNAME=user
MONGODB_PASSWORD=laravel
MONGODB_URI=mongodb://${MONGODB_USERNAME}:${MONGODB_PASSWORD}@mongodb:27017

为了将 MongoDB 与应用无缝集成,你可以安装由 MongoDB 官方维护的包。

若要从本地机器连接到应用的 MongoDB 数据库,你可以使用图形化界面,例如 Compass。默认情况下,MongoDB 数据库可在 localhost 的 27017 端口访问。

Redis

应用的 compose.yaml 文件中还包含一个 Redis 容器的条目。该容器使用了 Docker 卷,因此即便停止并重启容器,存储在 Redis 实例中的数据也会得以持久化。容器启动后,你可以在应用的 .env 文件中将 REDIS_HOST 环境变量设置为 redis,从而在应用内连接到 Redis 实例。

若要从本地机器连接到应用的 Redis 数据库,你可以使用图形化数据库管理工具,例如 TablePlus。默认情况下,Redis 数据库可在 localhost 的 6379 端口访问。

Valkey

如果在安装 Sail 时选择安装 Valkey 服务,应用的 compose.yaml 文件中就会包含一个 Valkey 的条目。该容器使用了 Docker 卷,因此即便停止并重启容器,存储在 Valkey 实例中的数据也会得以持久化。你可以在应用的 .env 文件中将 REDIS_HOST 环境变量设置为 valkey,从而在应用内连接到该容器。

若要从本地机器连接到应用的 Valkey 数据库,你可以使用图形化数据库管理工具,例如 TablePlus。默认情况下,Valkey 数据库可在 localhost 的 6379 端口访问。

Meilisearch

如果在安装 Sail 时选择了安装 Meilisearch 服务,应用的 compose.yaml 文件中就会包含这个与 Laravel Scout 集成的强大搜索引擎的条目。容器启动后,你可以在应用内将 MEILISEARCH_HOST 环境变量设置为 http://meilisearch:7700,从而连接到 Meilisearch 实例。

在本地机器上,你可以打开网页浏览器,访问 http://localhost:7700,以此进入 Meilisearch 的网页管理面板。

Typesense

如果在安装 Sail 时选择了安装 Typesense 服务,应用的 compose.yaml 文件中就会包含这个速度极快、且与 Laravel Scout 原生集成的开源搜索引擎的条目。容器启动后,你可以通过设置以下环境变量,在应用内连接到 Typesense 实例:

TYPESENSE_HOST=typesense
TYPESENSE_PORT=8108
TYPESENSE_PROTOCOL=http
TYPESENSE_API_KEY=xyz

在本地机器上,你可以通过 http://localhost:8108 访问 Typesense 的 API。

文件存储

如果在生产环境运行应用时,你打算使用 Amazon S3 来存储文件,那么在安装 Sail 时,你可能希望安装 RustFS 服务。RustFS 提供了兼容 S3 的 API,你可以借助它进行本地开发,使用 Laravel 的 s3 文件存储驱动,而无需在生产环境的 S3 中创建“测试”存储桶。如果在安装 Sail 时选择安装 RustFS,应用的 compose.yaml 文件中就会添加一个 RustFS 配置部分。

默认情况下,应用的 filesystems 配置文件中已经包含了针对 s3 磁盘的磁盘配置。除了使用该磁盘与 Amazon S3 交互,你还可以通过修改控制其配置的相关环境变量,将其用于与 RustFS 等任意兼容 S3 的文件存储服务进行交互。例如,在使用 RustFS 时,文件系统的环境变量配置应如下所示:

FILESYSTEM_DISK=s3
AWS_ACCESS_KEY_ID=sail
AWS_SECRET_ACCESS_KEY=password
AWS_DEFAULT_REGION=us-east-1
AWS_BUCKET=local
AWS_ENDPOINT=http://rustfs:9000
AWS_USE_PATH_STYLE_ENDPOINT=true

运行测试

Laravel 开箱即用地提供了出色的测试支持,你可以使用 Sail 的 test 命令来运行应用的功能测试和单元测试。Pest / PHPUnit 支持的任何 CLI 选项也可以传递给 test 命令:

sail test

sail test --group orders

Sail 的 test 命令等效于运行 test Artisan 命令:

sail artisan test

默认情况下,Sail 会创建一个专用的 testing 数据库,以确保测试不会干扰数据库的当前状态。在默认的 Laravel 安装中,Sail 还会配置 phpunit.xml 文件,以便在执行测试时使用该数据库:

<env name="DB_DATABASE" value="testing"/>

Laravel Dusk

Laravel Dusk 提供了一个简洁、易用的浏览器自动化和测试 API。得益于 Sail,你无需在本地计算机上安装 Selenium 或其他工具就能运行这些测试。开始之前,请取消应用 compose.yaml 文件中 Selenium 服务的注释:

selenium:
    image: 'selenium/standalone-chrome'
    extra_hosts:
      - 'host.docker.internal:host-gateway'
    volumes:
        - '/dev/shm:/dev/shm'
    networks:
        - sail

接下来,确保应用 compose.yaml 文件中的 laravel.test 服务针对 selenium 有一项 depends_on 配置:

depends_on:
    - mysql
    - redis
    - selenium

最后,启动 Sail 并运行 dusk 命令,即可运行你的 Dusk 测试套件:

sail dusk

适用于 Apple Silicon 的 Selenium

如果你的本地机器搭载了 Apple Silicon 芯片,你的 selenium 服务必须使用 selenium/standalone-chromium 镜像:

selenium:
    image: 'selenium/standalone-chromium'
    extra_hosts:
        - 'host.docker.internal:host-gateway'
    volumes:
        - '/dev/shm:/dev/shm'
    networks:
        - sail

预览邮件

Laravel Sail 默认的 compose.yaml 文件中包含一个 Mailpit 服务的条目。Mailpit 会拦截本地开发过程中应用发送的邮件,并提供便捷的网页界面,方便你在浏览器中预览邮件内容。在使用 Sail 时,Mailpit 的默认主机为 mailpit,可通过 1025 端口访问:

MAIL_HOST=mailpit
MAIL_PORT=1025
MAIL_ENCRYPTION=null

当 Sail 运行时,你可以访问以下地址进入 Mailpit 网页界面:http://localhost:8025

如果在安装 Sail 时选择了安装 Mailtrap Local 服务,或者之后通过 sail:add Artisan 命令添加了该服务,应用的 compose.yaml 文件中就会包含这个邮件捕获服务的条目。Mailtrap Local 的默认主机为 mailtrap-local,可通过 3535 端口访问:

MAIL_HOST=mailtrap-local
MAIL_PORT=3535

当 Sail 运行时,你可以访问以下地址进入 Mailtrap Local 网页界面:http://localhost:3550

容器 CLI

有时,你可能希望在应用的容器内开启一个 Bash 会话。你可以使用 shell 命令连接到应用的容器,从而查看容器中的文件和已安装的服务,并且在容器内执行任意 shell 命令:

sail shell

sail root-shell

若要开启一个新的 Laravel Tinker 会话,你可以执行 tinker 命令:

sail tinker

PHP 版本

Sail 目前支持通过 PHP 8.5、8.4、8.3、8.2、8.1 或 PHP 8.0 来运行你的应用。Sail 当前默认使用的 PHP 版本为 PHP 8.5。若要更改运行应用所用的 PHP 版本,你应该更新应用 compose.yaml 文件中 laravel.test 容器的 build 定义:

# PHP 8.5
context: ./vendor/laravel/sail/runtimes/8.5

# PHP 8.4
context: ./vendor/laravel/sail/runtimes/8.4

# PHP 8.3
context: ./vendor/laravel/sail/runtimes/8.3

# PHP 8.2
context: ./vendor/laravel/sail/runtimes/8.2

# PHP 8.1
context: ./vendor/laravel/sail/runtimes/8.1

# PHP 8.0
context: ./vendor/laravel/sail/runtimes/8.0

此外,你可能希望更新 image 名称,以体现应用所使用的 PHP 版本。该选项同样定义在应用的 compose.yaml 文件中:

image: sail-8.2/app

更新应用的 compose.yaml 文件后,你应该重新构建容器镜像:

sail build --no-cache

sail up

额外 PHP 扩展

Sail 的运行时镜像包含一组常用的 PHP 扩展。如果你的应用需要额外扩展,可以在构建镜像时,在应用 compose.yaml 文件的 laravel.test 服务中添加一个以空格分隔的 PHP_EXTENSIONS 构建参数来安装这些扩展:

build:
    args:
        WWWGROUP: '${WWWGROUP}'
        PHP_EXTENSIONS: 'gmp imagick'

更新应用的 compose.yaml 文件后,你应该重新构建容器镜像。

Node 版本

Sail 默认安装 Node 24。若要更改构建镜像时安装的 Node 版本,你可以更新应用 compose.yaml 文件中 laravel.test 服务的 build.args 定义:

build:
    args:
        WWWGROUP: '${WWWGROUP}'
        NODE_VERSION: '18'

更新应用的 compose.yaml 文件后,你应该重新构建容器镜像:

sail build --no-cache

sail up

共享站点

有时你可能需要公开共享你的站点,以便向同事预览站点,或者测试应用的 Webhook 集成。若要共享站点,可以使用 share 命令。执行此命令后,你会获得一个随机的 laravel-sail.site URL,用于访问你的应用:

sail share

当通过 share 命令共享站点时,你应该使用应用 bootstrap/app.php 文件中的 trustProxies 中间件方法配置应用的可信代理。否则,诸如 url 和 route 之类的 URL 生成辅助函数将无法确定生成 URL 时应使用的正确的 HTTP 主机:

->withMiddleware(function (Middleware $middleware): void {
    $middleware->trustProxies(at: '*');
})

如果你希望为共享站点选择子域名,可以在执行 share 命令时提供 subdomain 选项:

sail share --subdomain=my-sail-site

share 命令由 Expose 提供支持,这是一个由 BeyondCode 提供的开源隧道服务。

使用 Xdebug 调试

Laravel Sail 的 Docker 配置支持 Xdebug,这是一个广受欢迎的、功能强大的 PHP 调试器。若要启用 Xdebug,请确保你已发布 Sail 配置。然后,将以下变量添加到应用的 .env 文件中以配置 Xdebug:

SAIL_XDEBUG_MODE=develop,debug,coverage

接着,确保你已发布的 php.ini 文件包含以下配置,以便在指定模式下激活 Xdebug:

[xdebug]
xdebug.mode=${XDEBUG_MODE}

修改 php.ini 文件后,记得重新构建 Docker 镜像,以便 php.ini 文件的更改生效:

sail build --no-cache

Linux 主机 IP 配置

在内部,XDEBUG_CONFIG 环境变量被定义为 client_host=host.docker.internal,以便 Xdebug 在 Mac 和 Windows(WSL2)上能被正确配置。如果你的本地机器运行的是 Linux 且使用 Docker 20.10 及以上版本,host.docker.internal 可用,无需手动配置。

对于低于 20.10 的 Docker 版本,Linux 不支持 host.docker.internal,你需要手动定义主机 IP。为此,你可以在 compose.yaml 文件中定义自定义网络,为容器配置静态 IP:

networks:
  custom_network:
    ipam:
      config:
        - subnet: 172.20.0.0/16

services:
  laravel.test:
    networks:
      custom_network:
        ipv4_address: 172.20.0.2

设置好静态 IP 后,在应用的 .env 文件中定义 SAIL_XDEBUG_CONFIG 变量:

SAIL_XDEBUG_CONFIG="client_host=172.20.0.2"

Xdebug 命令行使用

可以使用 sail debug 命令,在运行 Artisan 命令时启动调试会话:

# Run an Artisan command without Xdebug...
sail artisan migrate

# Run an Artisan command with Xdebug...
sail debug migrate

Xdebug 浏览器使用

若要在通过 Web 浏览器与应用交互时调试应用,请按照 Xdebug 提供的说明,从 Web 浏览器发起 Xdebug 会话。

如果你使用的是 PhpStorm,请查阅 JetBrains 关于 零配置调试 的文档。

Laravel Sail 依赖 artisan serve 来运行你的应用。自 Laravel 8.53.0 版本起,artisan serve 命令仅接受 XDEBUG_CONFIG 和 XDEBUG_MODE 变量。较旧版本的 Laravel(8.52.0 及以下)不支持这些变量,也无法接受调试连接。

自定义

由于 Sail 本质上就是 Docker,你可以自由地对它的几乎所有内容进行自定义。若要发布 Sail 自身的 Dockerfile,可以执行 sail:publish 命令:

sail artisan sail:publish

运行该命令后,Laravel Sail 所使用的 Dockerfile 及其他配置文件将被放置在应用根目录下的 docker 目录中。在自定义 Sail 安装后,你可能希望更改应用 compose.yaml 文件中应用容器的镜像名称。完成此操作后,使用 build 命令重新构建应用的容器。如果你使用 Sail 在同一台机器上开发多个 Laravel 应用,为应用镜像指定唯一名称尤为重要:

sail build --no-cache