Laravel Sail

簡介

Laravel Sail 是一個輕量的命令列介面,可用來操作 Laravel 預設的 Docker 開發環境。對於使用 PHP、MySQL 與 Redis 來建立 Laravel 專案,Sail 是一個不錯的入門選項,且不需預先具備有關 Docker 的知識。

Sail 的核心是保存在專案根目錄的 docker-compose.yml 檔案與 sail Script 檔。sail Script 檔提供了一個有許多方便方法的 CLI 介面,能操作由 docker-compose.yml 檔案所定義的 Docker Container。

Laravel Sail 支援 macOS、Linux、與 Windows (通過 WSL2)。

安裝與設定

Laravel Sail 已自動安裝到新的 Laravel 專案中,因此你可以馬上開始使用 Sail。若要瞭解如何建立新的 Laravel 專案,請參考 Laravel 的安裝說明文件中對應你的作業系統的部分。在安裝時,Sail 會詢問你的專案要用到哪些 Sail 支援的服務。

將 Sail 安裝到現有的專案

若想在現有的 Laravel 專案中安裝 Sail,只需要使用 Composer 套件管理員安裝 Sail 即可。當然,這個步驟假設你已經有假設好本機開發環境,才能安裝 Composer 套件:

1composer require laravel/sail --dev
1composer require laravel/sail --dev

安裝好 Sail 後,可以執行 sail:install Artisan 指令。這個指令會將 Sail 的 docker-compose.yml 檔案安裝到專案根目錄:

1php artisan sail:install
1php artisan sail:install

最後,可啟動 Sail。若要繼續瞭解有關如何使用 Sail 的資訊,請繼續閱讀本說明文件中剩下的部分:

1./vendor/bin/sail up
1./vendor/bin/sail up

新增額外服務

若想在現有的 Sail 專案中加上更多服務,可以執行 sail:add Artisan 指令:

1php artisan sail:add
1php artisan sail:add

使用 Devcontainer

若要使用 Devcontainer 來開發,可在執行 sail:install 指令時提供 --devcontainer 選項。--devcontainer 選項會讓 sail:install 指令將一個預設的 .devcontainer/devcontainer.json 檔案安裝到專案根目錄下:

1php artisan sail:install --devcontainer
1php artisan sail:install --devcontainer

設定 Shell Alias

預設情況下,Sail 指令是使用 vendor/bin/sail Script 檔來呼叫的。該 Script 檔包含在所有新安裝的 Laravel 專案內:

1./vendor/bin/sail up
1./vendor/bin/sail up

不過,我們可以設定 Shell Alias 以更輕鬆地執行 Sail 指令,而不需要一直重複鍵入 vendor/bin/sail

1alias sail='[ -f sail ] && sh sail || sh vendor/bin/sail'
1alias sail='[ -f sail ] && sh sail || sh vendor/bin/sail'

為了確保此 Alias 設定總是有效,可以將此設定加到你的家目錄中的 Shell 設定檔內。如 ~/.zshrc~/.bashrc,接著重新啟動 Shell。

設定好 Shell Alias 後,只要鍵入 sail 就可執行 Sail 指令。此說明文件剩下的部分都假設你已設定好此 Alias:

1sail up
1sail up

啟動與停止 Sail

Laravel Sail 的 docker-compose.yml 中定義了數個 Docker Container,這些 Container 會互相配合來協助你製作 Laravel 專案。在 docker-compose.yml 檔案中,services 設定內的每一格項目都是一個 Container。laravel.test Container 是專案的主要 Container,用來執行你的專案:

啟動 Sail 後,請確定你的本機電腦上沒有執行其他 Web Server(網頁伺服器)或資料庫。若要啟動所有 docker-compose.yml 檔案中的 Docker Container,請執行 up 指令:

1sail up
1sail up

若要在背景啟動所有 Docker Container,可使用「分離模式 (Detached Mode)」啟動 Sail:

1sail up -d
1sail up -d

啟動專案的 Docker Container 後,就可以在瀏覽器中開啟 http://localhost 來存取網站。

若要停止所有 Container,只需要按 Ctrl + C 來停止執行 Container 即可。如果 Container 是在背景執行,可使用 stop 指令:

1sail stop
1sail stop

執行指令

在使用 Laravel Sail 時,你的專案會被放在 Docker Container 內執行,並與你的本機電腦隔離。不過,Sail 提供了一個方便的方法,可讓你針對你的專案執行各種指令,如:執行任意 PHP 指令、Artisan 指令、Node 與 NPM 指令等。

在閱讀 Laravel 的說明文件時,有時候會看到一些沒有提到 Sail 的 Composer、Artisan、Node 或 NPM 指令。這些範例假設這些工具是安裝在你的本機電腦上。使用 Laravel Sail 作為本機開發環境時,應使用 Sail 來執行這些指令:

1# 在本機執行 Artisan 指令...
2php artisan queue:work
3 
4# 在 Laravel Sail 內執行 Artisan 指令...
5sail artisan queue:work
1# 在本機執行 Artisan 指令...
2php artisan queue:work
3 
4# 在 Laravel Sail 內執行 Artisan 指令...
5sail artisan queue:work

執行 PHP 指令

可以使用 php 指令來執行 PHP 指令。當然,這些指令會使用你的專案所設定的 PHP 版本來執行。有關 Laravel Sail 中可用的 PHP 版本,請參考 PHP 版本的說明文件

1sail php --version
2 
3sail php script.php
1sail php --version
2 
3sail php script.php

執行 Composer 指令

Composer 指令可使用 composer 指令執行。Laravel Sail 的應用程式 Container 中包含了 Composer 2.x:

1sail composer require laravel/sanctum
1sail composer require laravel/sanctum

為現有專案安裝 Composer 相依性套件

若與團隊一起開發專案,則讀者可能不是最初新建 Laravel 專案的人。因此,當你將專案的存放庫 Clone 到本機電腦上時,專案中包含 Sail 在內的所有 Composer 相依性套件都還未安裝。

打開專案目錄並執行下列指令即可安裝專案的相依性套件。這個指令會使用一個包含 PHP 與 Composer 的小型 Docker Container 來安裝專案的相依性套件:

1docker run --rm \
2 -u "$(id -u):$(id -g)" \
3 -v "$(pwd):/var/www/html" \
4 -w /var/www/html \
5 laravelsail/php82-composer:latest \
6 composer install --ignore-platform-reqs
1docker run --rm \
2 -u "$(id -u):$(id -g)" \
3 -v "$(pwd):/var/www/html" \
4 -w /var/www/html \
5 laravelsail/php82-composer:latest \
6 composer install --ignore-platform-reqs

使用 laravelsail/phpXX-composer Image(映像) 時,請使用與你的專案相同的 PHP 版本 (74, 80, 81, 82)。

執行 Artisan 指令

可使用 `artisan 指令來執行 Laravel Artisan 指令:

1sail artisan queue:work
1sail artisan queue:work

執行 Node 與 NPM 指令

可使用 node 指令來執行 Node 指令,而 npm 指令可用來執行 NPM 指令:

1sail node --version
2 
3sail npm run dev
1sail node --version
2 
3sail npm run dev

若有需要,除了 NPM 外也可使用 Yarn:

1sail yarn
1sail yarn

使用資料庫

MySQL

讀者可能已經注意到,專案的 docker-compose.yml 中有包含 MySQL Container 的設定。這個 Container 使用 Docker Volume,這樣一來就算停止或重新啟動 Container,保存在資料庫中的資料也不會不見。

此外,第一次啟動 MySQL Container 時,該 Container 會幫你建立兩個資料庫。第一個資料庫會使用 DB_DATABASE 環境變數所設定的名稱,作為本機開發之用。第二個資料庫是專門用來測試的,名稱為 test,用來確保測試時不會影響到開發資料。

啟動 Container 後,可以在專案的 .env 檔案中將 DB_HOST 環境變數設為 mysql 來讓網站連線到 MySQL 實體。

若要從本機上連線到專案的 MySQL 資料庫,可使用圖形化的資料庫管理工具,如 TablePlus。預設情況下,可以在 localhost 的 3306 連接埠上存取 MySQL 資料庫,而帳號密碼則對應到 DB_USERNAMEDB_PASSWORD 環境變數。或者,也可以使用 root 使用者來連線,其密碼一樣是 DB_PASSWORD 環境變數值。

Redis

專案的 docker-compose.yml 檔案中也包含了 Redis Container 的設定。這個 Container 使用了 Docker volume,這樣一來即使停止或重新啟動 Container,保存在 Redis 裡的資料也不會不見。啟動 Container 後,只要將 .env 檔中的 REDIS_HOST 環境變數設為 redis,就可讓網站連線到 Redis 實體。

若要從本機電腦連線到專案的 Redis 資料庫,可以使用如 TablePlus 等的圖形化資料庫管理程式。預設情況下,可以使用 localhost 的 6379 連接埠來存取 Redis 資料庫。

MeiliSearch

若在安裝 Sail 時有選擇安裝 MeiliSearch,則專案的 docker-compose.yml 檔中也會包含 MeiliSearch 的設定。MeiliSearch 是一個強大的搜尋引擎,與 Laravel Scout 相容。啟動 Container 後,只要將 MEILISEARCH_HOST 環境變數設為 http://meilisearch:7700 即可讓網站連線到 MeiliSearch 實體。

在本機上,只要在瀏覽器上打開 http://localhost:7700,就可存取 MeiliSearch 的網頁管理面板。

檔案儲存

若打算在正式環境使用 Amazon S3 來儲存檔案,則建議在安裝 Sail 時安裝 MinIO 服務。MinIO 提供了與 S3 相容的 API,讓你可以在本機開發時不用在正式的 S3 環境上建立測試用的 Bucket,就能使用 Laravel 的 s3 檔案儲存 Driver。若在安裝 Sail 時有選擇安裝 MinIO,則 docker-compose.yml 檔案中就會有 MinIO 相關的設定。

預設情況下,專案中的 filesystems 設定檔內已經有包含 s3 Disk 的設定了。除了通過此 Disk 來使用 Amazon S3 外,只要修改該設定相關的環境變數,就可以通過這個 Disk 來使用任何如 MinIO 等 S3 相容的檔案儲存服務。舉例來說,使用 MinIO 時,應像這樣定義 Filesystem(檔案系統) 環境變數:

1FILESYSTEM_DISK=s3
2AWS_ACCESS_KEY_ID=sail
3AWS_SECRET_ACCESS_KEY=password
4AWS_DEFAULT_REGION=us-east-1
5AWS_BUCKET=local
6AWS_ENDPOINT=http://minio:9000
7AWS_USE_PATH_STYLE_ENDPOINT=true
1FILESYSTEM_DISK=s3
2AWS_ACCESS_KEY_ID=sail
3AWS_SECRET_ACCESS_KEY=password
4AWS_DEFAULT_REGION=us-east-1
5AWS_BUCKET=local
6AWS_ENDPOINT=http://minio:9000
7AWS_USE_PATH_STYLE_ENDPOINT=true

為了讓 Laravel 的 Flysystem 整合在使用 MinIO 時整合正確的 URL,請定義 AWS_URL 環境變數,並設定適用於專案本機 URL 的值,且該值應在 URL 路徑內包含 Bucket 名稱:

1AWS_URL=http://localhost:9000/local
1AWS_URL=http://localhost:9000/local

可以使用 MinIO Console 來建立 Bucket。MinIO Console 可從 http://localhost:8900 開啟。MinIO Console 預設的使用者名稱是 sail,預設密碼為 password

exclamation

使用 MinIO 時,不支援通過 temporaryUrl 方法來產生臨時儲存空間 URL。

執行測試

Laravel 內建了許多測試輔助功能。可以使用 Sail 的 test 指令來執行專案的 Feature Test 與 Unit Test。可以傳入任何 PHPUnit 支援的 CLI 選項給 test 指令:

1sail test
2 
3sail test --group orders
1sail test
2 
3sail test --group orders

Sail 的 test 指令與執行 test Artisan 指令相同:

1sail artisan test
1sail artisan test

預設情況下,Sail 會建立一個專門的 testing 資料庫,以避免測試時影響到目前資料庫的狀態。在預設的 Laravel 專案中,Sail 也會調整 phpunit.xml 檔的設定,以在執行測試時使用這個資料庫:

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

Laravel Dusk

Laravel Dusk 提供了豐富且簡單易用的瀏覽器自動化與測試 API。多虧有 Sail,我們不需要在本機電腦上安裝 Selenium 或其他工具,就能執行這些 Dusk 測試。若要開始使用 Dusk,請先在專案的 docker-compose.yml 檔案中將 Slenium 服務取消註解:

1selenium:
2 image: 'selenium/standalone-chrome'
3 volumes:
4 - '/dev/shm:/dev/shm'
5 networks:
6 - sail
1selenium:
2 image: 'selenium/standalone-chrome'
3 volumes:
4 - '/dev/shm:/dev/shm'
5 networks:
6 - sail

接著,請確保專案的 docker-compose.yml 檔案中,laravel.test 服務的 depends_on 欄位中有 selenium

1depends_on:
2 - mysql
3 - redis
4 - selenium
1depends_on:
2 - mysql
3 - redis
4 - selenium

最後,只要啟動 Sail 並執行 dusk 指令,就能執行 Dusk 的測試套件:

1sail dusk
1sail dusk

在 Apple Silicon 上的 Selenium

如果你的本機設備為 Apple Silicon 晶片,則 selenium 服務必須使用 seleniarm/standalone-chromium Image:

1selenium:
2 image: 'seleniarm/standalone-chromium'
3 volumes:
4 - '/dev/shm:/dev/shm'
5 networks:
6 - sail
1selenium:
2 image: 'seleniarm/standalone-chromium'
3 volumes:
4 - '/dev/shm:/dev/shm'
5 networks:
6 - sail

預覽 E-Mail

Laravel Sail 的預設 docker-compose.yml 檔案中包含了 Mailpit 服務。Mailpit 會在本機開發過程中攔截你的專案所寄出的所有 E-Mail,並提供一個方便的 Web 界面可供你在瀏覽器中預覽這些 E-Mail 訊息。使用 Sail 時,Mailpit 的預設主機名稱為 mailpit,且可在連接埠 1025 上使用:

1MAIL_HOST=mailpit
2MAIL_PORT=1025
3MAIL_ENCRYPTION=null
1MAIL_HOST=mailpit
2MAIL_PORT=1025
3MAIL_ENCRYPTION=null

當 Sail 有在執行時,可在此處存取 Mailpit 的 Web 界面:http://localhost:8025

Container CLI

有時候,我們可能會需要在專案的 Container 內開啟 Bash 工作階段。可以使用 shell 指令來連線到專案的 Container 中,讓我們能檢視其中的檔案與所安裝的服務,並可在 Container 中執行任意 Shell 指令:

1sail shell
2 
3sail root-shell
1sail shell
2 
3sail root-shell

若要啟動新的 Laravel Tinker 工作階段,可執行 tinker 指令:

1sail tinker
1sail tinker

PHP 版本

Sail 目前支援使用 PHP 8.2、8.1、PHP 8.0、或 PHP 7.4 來執行你的專案。目前 Sail 所使用的預設 PHP 版本為 PHP 8.2。若要修改專案使用的 PHP 版本,請更新 docker-compose.yml 檔案中 laravel.test Container 的 build 定義:

1# PHP 8.2
2context: ./vendor/laravel/sail/runtimes/8.2
3 
4# PHP 8.1
5context: ./vendor/laravel/sail/runtimes/8.1
6 
7# PHP 8.0
8context: ./vendor/laravel/sail/runtimes/8.0
9 
10# PHP 7.4
11context: ./vendor/laravel/sail/runtimes/7.4
1# PHP 8.2
2context: ./vendor/laravel/sail/runtimes/8.2
3 
4# PHP 8.1
5context: ./vendor/laravel/sail/runtimes/8.1
6 
7# PHP 8.0
8context: ./vendor/laravel/sail/runtimes/8.0
9 
10# PHP 7.4
11context: ./vendor/laravel/sail/runtimes/7.4

此外,也可更新 image 的名稱,以反應專案所使用的 PHP 版本。image 名稱的設定在專案的 docker-compose.yml 檔內:

1image: sail-8.1/app
1image: sail-8.1/app

更新好專案的 docker-compose.yml 後,請重新建置 Container Image:

1sail build --no-cache
2 
3sail up
1sail build --no-cache
2 
3sail up

Node 版本

預設情況下 Sail 會安裝 Node 18。若要更改建置 Image 時使用的 Node 版本,請更新專案中 docker-compose.yml 檔案內 laravel.test 服務的 build.args 定義:

1build:
2 args:
3 WWWGROUP: '${WWWGROUP}'
4 NODE_VERSION: '14'
1build:
2 args:
3 WWWGROUP: '${WWWGROUP}'
4 NODE_VERSION: '14'

更新好專案的 docker-compose.yml 後,請重新建置 Container Image:

1sail build --no-cache
2 
3sail up
1sail build --no-cache
2 
3sail up

共享網站

有時候,我們需要公開地共享我們的網站,好讓同事能預覽網站,或是能測試專案中的 Webhook 整合。若要共享網站,可以使用 share 指令。執行該指令後,會分配一個隨機的 laravel-sail.site 網址能讓你存取你的網站:

1sail share
1sail share

在使用 share 指令共享網站時,應設定在 TrustProxies Middleware 中設定專案的 Trusted Proxies。否則,如 urlroute 等產生 URL 用的輔助函式在產生 URL 時將無法判正確的 HTTP 主機名稱:

1/**
2 * The trusted proxies for this application.
3 *
4 * @var array|string|null
5 */
6protected $proxies = '*';
1/**
2 * The trusted proxies for this application.
3 *
4 * @var array|string|null
5 */
6protected $proxies = '*';

若要選擇共享網站時使用的子網域,可在執行 share 指令時提供 subdomain 選項:

1sail share --subdomain=my-sail-site
1sail share --subdomain=my-sail-site
lightbulb

share 指令由 Expose 驅動。Expose 是由 BeyondCode 提供的,開放原始碼的通道 (Tunneling) 服務。

使用 Xdebug 進行除錯

Laravel Sail 的 Docker 設定中也包含了對 Xdebug 的支援。Xdebug 是一個常用且強大的 PHP 除錯工具。若要啟用 Xdebug,需要先在專案的 .env 檔中加上一些變數來設定 Xdebug。若要啟用 Xdebug,必須在啟動 Sail 前先設定適當的模式 (Mode):

1SAIL_XDEBUG_MODE=develop,debug,coverage
1SAIL_XDEBUG_MODE=develop,debug,coverage

Linux 主機的 IP 設定

在 Laravel Sail 中,XDEBUG_CONFIG 環境變數被設定為 client_host=host.docker.internal,好讓 Xdebug 能在 Mac 與 Windows (WSL2) 下被正確設定。如果你的本機裝置使用 Linux,請確保使用 17.06.0 版或更新的 Docker Engine 以及 1.16.0 版或更新的 Composer。否則,就需要像下面這樣手動定義環境變數:

首先,需要先執行下列指令來判斷要加到環境變數中的正確主機 IP 位址。一般來說,<container-name> 應為你的專案使用的 Container 名稱,通常以 _laravel.test_1 結尾:

1docker inspect -f {{range.NetworkSettings.Networks}}{{.Gateway}}{{end}} <container-name>
1docker inspect -f {{range.NetworkSettings.Networks}}{{.Gateway}}{{end}} <container-name>

取得正確的主機 IP 後,請在專案的 .env 檔中定義 SAIL_XDEBUG_CONFIG 變數:

1SAIL_XDEBUG_CONFIG="client_host=<host-ip-address>"
1SAIL_XDEBUG_CONFIG="client_host=<host-ip-address>"

使用 Xdebug CLI

sail debug 指令可用來在執行 Artisan 指令時啟動除錯工作階段:

1# 執行 Artisan 指令,且不使用 Xdebug...
2sail artisan migrate
3 
4# 執行 Artisan 指令,並使用 Xdebug...
5sail debug migrate
1# 執行 Artisan 指令,且不使用 Xdebug...
2sail artisan migrate
3 
4# 執行 Artisan 指令,並使用 Xdebug...
5sail debug migrate

使用 Xdebug Browser

若要在通過 Web 瀏覽器瀏覽網站時對網站進行除錯,請依照Xdebug 所提供的說明來在 Web 瀏覽器中啟動 Xdebug 工作階段。

若使用 PhpStorm,請參考 JetBrains 的零設定除錯說明文件。

exclamation

Laravel Sail 仰賴 artisan serve 來執行網站。只有在 8.53.0 版之後的 Laravel 中,artisan serve 指令才會接受 XDEBUG_CONFIGXDEBUG_MODE 變數。舊版的 Laravel (8.52.0 版以前) 不接受這些變數,且不會接受除錯連線。

自定

由於 Sail 就是 Docker,因此你幾乎可以對 Sail 中的任何部分進行自定。若要安裝 Sail 的 Dockerfile,可執行 sail:publish 指令:

1sail artisan sail:publish
1sail artisan sail:publish

執行該指令後,Laravel Sail 所使用的 Dockerfile 與其他設定檔會被放到專案根目錄中的 docker 目錄下。調整了 Sail 設定後,你可能會想在 docker-compose.yml 中更改專案 Container 所使用的 Image 名稱。之後,請使用 build 指令來重新建置專案的 Image。如果你在同一台裝置上開發多個 Laravel 專案,那麼請務必為 Image 設定不重複的名稱:

1sail build --no-cache
1sail build --no-cache
翻譯進度
100% 已翻譯
更新時間:
2023年6月29日 上午10:33:00 [世界標準時間]
翻譯人員:
  • cornch
幫我們翻譯此頁

留言

尚無留言

“Laravel” is a Trademark of Taylor Otwell.
The source documentation is released under MIT license. See laravel/docs on GitHub for details.
The translated documentations are released under MIT license. See cornch/laravel-docs-l10n on GitHub for details.