LaravelDocs(中文)

Sail (Laravel Sail)

Sail 是 Laravel 的輕量命令列介面

簡介 (Introduction)

Laravel Sail 是一個輕量的命令列介面,用來管理 Laravel 預設的 Docker 開發環境。Sail 提供了一個快速且無痛的起點,讓你可以使用 PHP、MySQL 和 Redis 建置 Laravel 應用程式,而不需要事先具備 Docker 的使用經驗。

Sail 的核心包含專案根目錄下的 compose.yaml 檔與 sail 腳本。sail 腳本提供了方便的 CLI 指令,用以操作 compose.yaml 所定義的 Docker 容器。

Laravel Sail 支援 macOS、Linux,以及透過 WSL2 的 Windows。

安裝與設定 (Installation)

Laravel Sail 會自動隨所有新的 Laravel 專案安裝,因此你可以立即開始使用。

在既有專案中安裝 Sail (Installing Sail Into Existing Applications)

如果想在既有的 Laravel 專案中使用 Sail,可以透過 Composer 套件管理器安裝。下列步驟假設你的本機開發環境允許安裝 Composer 相依套件:

composer require laravel/sail --dev

安裝 Sail 後,你可以執行 sail:install Artisan 指令。此指令會將 Sail 的 compose.yaml 發佈到應用程式的根目錄,並更新 .env,加入連接 Docker 服務所需的環境變數:

php artisan sail:install

最後,啟動 Sail 即可開始使用;更多使用方式請繼續閱讀下方文件內容:

./vendor/bin/sail up

[!WARNING] 如果你在 Linux 上使用 Docker Desktop,請使用 default Docker context,執行 docker context use default。若在容器內遇到檔案權限錯誤,可能需要將 SUPERVISOR_PHP_USER 環境變數設為 root

新增額外服務 (Adding Additional Services)

若要為現有 Sail 安裝新增其他服務,可執行 sail:add Artisan 指令:

php artisan sail:add

使用 Devcontainer (Using Devcontainers)

如果你希望在 Devcontainer 中開發,執行 sail:install 時可以加上 --devcontainer 選項,此選項會將預設的 .devcontainer/devcontainer.json 檔發佈到應用程式根目錄:

php artisan sail:install --devcontainer

重新建立 Sail 映像檔 (Rebuilding Sail Images)

有時你會想要完全重建 Sail 映像,以確保映像內的套件與軟體皆為最新,這可以使用 build 指令完成:

docker compose down -v

sail build --no-cache

sail up

設定 Shell Alias(別名) (Configuring A Shell Alias)

預設情況下,Sail 指令透過隨專案提供的 vendor/bin/sail 腳本呼叫:

./vendor/bin/sail up

若不想每次都輸入 vendor/bin/sail,可在 shell 設定一個 alias,讓執行 Sail 指令更便利:

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

要讓別名長期生效,請把它加入你家目錄的 shell 設定檔(例如 ~/.zshrc~/.bashrc),然後重啟 shell。

設定別名後,你可以直接使用 sail 執行指令;下方所有範例都假設你已設定別名:

sail up

啟動與停止 Sail (Starting And Stopping Sail)

Laravel Sail 的 compose.yaml 檔定義了一組協作的 Docker 容器,協助你開發 Laravel 應用。每個容器都是 compose.yamlservices 的一個項目,而 laravel.test 則為主要的應用容器,負責對外提供服務。

在啟動 Sail 前,請確認本機沒有其他網頁伺服器或資料庫佔用相同端口。要啟動 compose.yaml 中定義的所有容器,請執行 up 指令:

sail up

若要在背景啟動容器,請使用「分離(detached)」模式:

sail up -d

容器啟動後,可在瀏覽器中開啟 http://localhost 存取你的專案。

要停止容器,可在前台使用 Control + C;若容器在背景執行,則可使用 stop 指令:

sail stop

執行指令 (Executing Sail Commands)

使用 Laravel Sail 時,應用程式會在 Docker 容器中執行並與本機隔離。但 Sail 提供了方便的方式在容器內執行各種指令,例如 PHP、Artisan、Composer 與 Node / NPM 指令。

**在 Laravel 文件中你常會看到未以 Sail 呼叫的 Composer、Artisan 或 Node / NPM 指令。**那些範例假設相關工具已安裝於本機。若使用 Sail 作為本機開發環境,請改用 Sail 來執行這些指令:

# 在本機執行 Artisan 指令...
php artisan queue:work

# 在 Laravel Sail 容器中執行 Artisan 指令...
sail artisan queue:work

執行 PHP 指令 (Executing Php Commands)

你可以使用 php 指令在容器內執行 PHP,指令會以專案設定的 PHP 版本執行。如需了解 Sail 支援的 PHP 版本,請參考 PHP 版本說明

sail php --version

sail php script.php

執行 Composer 指令 (Executing Composer Commands)

在容器內可使用 composer 執行 Composer 指令,Sail 的應用容器已內建 Composer:

sail composer require laravel/sanctum

執行 Artisan 指令 (Executing Artisan Commands)

可在容器內使用 artisan 執行 Laravel Artisan 指令:

sail artisan queue:work

執行 Node / NPM 指令 (Executing Node Npm Commands)

Node 指令可使用 node 執行;NPM 指令可使用 npm 執行:

sail node --version

sail npm run dev

如果你願意,也可以使用 Yarn 取代 NPM:

sail yarn

與資料庫互動 (Interacting With Sail Databases)

MySQL

如你所見,compose.yaml 中包含 MySQL 服務。該容器使用 Docker volume 來確保資料持久化,即使停止或重啟容器也能保留資料。

首次啟動 MySQL 容器時,會為你建立兩個資料庫:第一個以 .env 中的 DB_DATABASE 命名供開發使用;第二個為 testing,供測試使用以避免干擾開發資料。

啟動容器後,於應用程式中要連線 MySQL,只需在 .envDB_HOST 設為 mysql

若要從本機連線到專案的 MySQL,可使用圖形化管理工具(如 TablePlus),預設可透過 localhost:3306 存取。連線帳號與密碼對應於 .env 中的 DB_USERNAMEDB_PASSWORD。你也可使用 root 帳號,其密碼同為 DB_PASSWORD 的值。

MongoDB

若在安裝 Sail 時選擇啟用 MongoDB 服務,compose.yaml 會包含 MongoDB Atlas Local 的容器設定(提供 Atlas 功能如 Search Indexes)。該容器同樣使用 Docker volume 以保持資料持久化。

啟動容器後,於應用程式中連線 MongoDB,請將 .envMONGODB_URI 設為 mongodb://mongodb:27017。預設未啟用認證;若要啟用,可在啟動 mongodb 容器前設定 MONGODB_USERNAMEMONGODB_PASSWORD,並把憑證加入連線字串:

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

如需更順暢地把 MongoDB 整合至你的應用,建議安裝 MongoDB 官方維護的 Laravel 套件(詳細說明)。

若要從本機連線 MongoDB,可使用圖形介面工具(如 Compass)。預設連接埠為 27017

Redis

compose.yaml 中也包含 Redis 服務。該容器使用 Docker volume 來保持數據持久化。啟動後,將 .envREDIS_HOST 設為 redis 即可在應用程式內連線到 Redis。

若要從本機連線 Redis,可使用像 TablePlus 之類的工具,預設連接埠為 6379

Valkey

若在安裝 Sail 時選擇加入 Valkey(https://valkey.io/),compose.yaml 會包含相應的服務設定。此容器同樣使用 Docker volume 以確保資料持久化。於應用程式中連線 Valkey,請把 .envREDIS_HOST 設為 valkey

從本機連線 Valkey 可使用圖形化管理工具(例如 TablePlus),預設連接埠為 6379

Meilisearch

若在安裝 Sail 時選擇 Meilisearch,compose.yaml 會包含該強大搜尋引擎的服務設定,並已與 Laravel Scout 整合。啟動容器後,將 .envMEILISEARCH_HOST 設為 http://meilisearch:7700 就可連線。

你也可以於本機瀏覽器開啟 http://localhost:7700 存取 Meilisearch 的管理介面。

Typesense

若在安裝 Sail 時選擇 Typesense(https://typesense.org),compose.yaml 會包含該高效能開源搜尋引擎的設定,並與 Laravel Scout 原生整合。啟動容器後,請在 .env 中設定以下環境變數以連線:

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

在本機上可透過 http://localhost:8108 存取 Typesense 的 API。

檔案儲存 (File Storage)

如果你在生產環境使用 Amazon S3 儲存檔案,可在安裝 Sail 時一併安裝 MinIO 服務。MinIO 提供與 S3 相容的 API,讓你在本機上使用 Laravel 的 s3 驅動進行開發,而不必在生產 S3 中建立測試用的 bucket。若選擇安裝 MinIO,compose.yaml 會新增 MinIO 的設定區塊。

預設情況下,專案的 filesystems 設定檔已包含 s3 磁碟設定。除了連線到 Amazon S3,透過修改環境變數你也能連接任何與 S3 相容的儲存服務,如 MinIO。以 MinIO 為例,相關 .env 設定如下:

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://minio:9000
AWS_USE_PATH_STYLE_ENDPOINT=true

為了讓 Laravel 的 Flysystem 在使用 MinIO 時能正確產生 URL,你應該定義 AWS_URL 環境變數,使其和應用程式的本機 URL 相符,且包含 bucket 名稱於 URL 路徑中:

AWS_URL=http://localhost:9000/local

你可以在 MinIO 管理介面 (http://localhost:8900) 中建立 bucket。MinIO 管理介面預設帳號為 sail,預設密碼為 password

[!WARNING] 使用 MinIO 時不支援透過 temporaryUrl 方法產生暫時性儲存 URL。

執行測試 (Running Tests)

Laravel 內建很棒的測試支援,你可以用 Sail 的 test 指令執行應用程式的 功能測試與單元測試。任何傳給 Pest / PHPUnit 的 CLI 選項也可傳給 test

sail test

sail test --group orders

Sail 的 test 指令等同於執行 Artisan 的 test 指令:

sail artisan test

預設情況下,Sail 會建立一個專用的 testing 資料庫,避免測試干擾開發資料。預設的 Laravel 安裝中,Sail 也會將 phpunit.xml 設定為使用該資料庫:

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

Laravel Dusk

Laravel Dusk 提供了簡潔且易用的瀏覽器自動化與測試 API。透過 Sail,你無需在本機安裝 Selenium 或其他外部工具即可運行 Dusk 測試。啟用 Dusk 的第一步是在 compose.yaml 中取消註解 Selenium 服務:

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

接著,確保 compose.yamllaravel.test 服務在 depends_on 中包含 selenium

depends_on:
  - mysql
  - redis
  - selenium

最後,啟動 Sail 並執行 dusk 指令即可運行 Dusk 測試:

sail dusk

在 Apple Silicon 上使用 Selenium (Selenium On Apple Silicon)

若你的機器為 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

郵件預覽 (Previewing Emails)

Sail 的預設 compose.yaml 包含 Mailpit 服務。Mailpit 會攔截本機開發期間應用發出的郵件,並提供瀏覽器中的簡易介面供你預覽郵件。Sail 中 Mailpit 的預設主機為 mailpit,郵件服務對外以埠號 1025 提供:

MAIL_HOST=mailpit
MAIL_PORT=1025
MAIL_ENCRYPTION=null

Sail 執行時,你可以在瀏覽器開啟 http://localhost:8025 存取 Mailpit 管理介面。

容器 CLI (Sail Container Cli)

你可以使用 shell 指令進入應用程式的容器開啟 Bash,檢查檔案、已安裝的服務或執行任意 shell 指令:

sail shell

sail root-shell

要啟動新的 Laravel Tinker 互動工作階段,可執行 tinker

sail tinker

PHP 版本 (Sail Php Versions)

Sail 目前支援以 PHP 8.4、8.3、8.2、8.1 或 8.0 提供應用程式服務;預設版本為 PHP 8.4。要變更應用使用的 PHP 版本,請在 compose.yamllaravel.test 容器 build 定義中更新對應路徑:

# 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

Node 版本 (Sail Node Versions)

Sail 預設會安裝 Node 22。若要變更建立映像時安裝的 Node 版本,請在 compose.yaml 中修改 laravel.test 服務的 build.args

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

修改 compose.yaml 後,請重建映像檔:

sail build --no-cache

sail up

分享你的網站 (Sharing Your Site)

有時你可能需要把本機網站公開分享給同事預覽或測試 webhook。使用 share 指令可以做到這件事;執行後會產生一個隨機的 laravel-sail.site URL 供你使用:

sail share

使用 share 分享網站時,請在 bootstrap/app.php 內透過 trustProxies middleware 設定受信任的代理(trusted proxies),否則 URL 生成輔助函式(如 urlroute)可能無法正確判斷主機:

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

若要自訂分享網站的子網域,可在執行 share 指令時提供 --subdomain 選項:

sail share --subdomain=my-sail-site

[!NOTE] > share 指令是由 Expose 支援,該服務由 BeyondCode 提供,是一套開放原始碼的穿透(tunneling)工具。

使用 Xdebug 偵錯 (Debugging With Xdebug)

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 映像以使變更生效:

sail build --no-cache

Linux 主機 IP 設定

內部 XDEBUG_CONFIG 預設為 client_host=host.docker.internal,可在 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 CLI 使用方式 (Xdebug Cli Usage)

可以使用 sail debug 指令在執行 Artisan 指令時啟動偵錯會話:

# 執行 Artisan 指令(無 Xdebug)...
sail artisan migrate

# 執行 Artisan 指令(含 Xdebug)...
sail debug migrate

Xdebug 瀏覽器端使用 (Xdebug Browser Usage)

若你想在瀏覽器互動的情況下偵錯應用程式,請參考 Xdebug 官方教學 以啟動瀏覽器端的 Xdebug 會話。

若使用 PhpStorm,請參閱 JetBrains 的 零設定偵錯文件 以取得更多說明。

[!WARNING] Laravel Sail 依賴 artisan serve 來提供應用程式服務。自 Laravel 8.53.0 開始,artisan serve 才接受 XDEBUG_CONFIGXDEBUG_MODE 變數;舊版(8.52.0 及更早)不支援,無法接受偵錯連線。

自訂化 (Sail Customization)

Sail 本質上就是 Docker,因此你可以自訂其中幾乎所有設定。要發佈 Sail 自帶的 Dockerfile 與相關設定檔,請執行 sail:publish 指令:

sail artisan sail:publish

執行後,Sail 使用的 Dockerfile 與其他設定檔會放在專案根目錄的 docker 目錄中。自訂完畢後,建議在 compose.yaml 中將應用容器的映像名稱改為獨一無二的名稱,然後使用 build 重新建立映像。若在同一台機器上以 Sail 開發多個 Laravel 專案,為映像指定唯一名稱尤其重要:

sail build --no-cache