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)。
Installation and Setup
Laravel Sail is automatically installed with all new Laravel applications so you may start using it immediately. To learn how to create a new Laravel application, please consult Laravel's installation documentation for your operating system. During installation, you will be asked to choose which Sail supported services your application will be interacting with.
將 Sail 安裝到現有的專案
若想在現有的 Laravel 專案中安裝 Sail,只需要使用 Composer 套件管理員安裝 Sail 即可。當然,這個步驟假設你已經有假設好本機開發環境,才能安裝 Composer 套件:
1composer require laravel/sail --dev
1composer require laravel/sail --dev
After Sail has been installed, you may run the sail:install
Artisan command. This command will publish Sail's docker-compose.yml
file to the root of your application and modify your .env
file with the required environment variables in order to connect to the Docker services:
1php artisan sail:install
1php artisan sail:install
最後,可啟動 Sail。若要繼續瞭解有關如何使用 Sail 的資訊,請繼續閱讀本說明文件中剩下的部分:
1./vendor/bin/sail up
1./vendor/bin/sail up
If you are using Docker Desktop for Linux, you should use the default
Docker context by executing the following command: docker context use default
.
新增額外服務
若想在現有的 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='sh $([ -f sail ] && echo sail || echo vendor/bin/sail)'
1alias sail='sh $([ -f sail ] && echo sail || echo vendor/bin/sail)'
為了確保此 Alias 設定總是有效,可以將此設定加到你的家目錄中的 Shell 設定檔內。如 ~/.zshrc
或 ~/.bashrc
,接著重新啟動 Shell。
設定好 Shell Alias 後,只要鍵入 sail
就可執行 Sail 指令。此說明文件剩下的部分都假設你已設定好此 Alias:
1sail up
1sail up
Starting and Stopping 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
Once the application's containers have been started, you may access the project in your web browser at: 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# Running Artisan commands locally...2php artisan queue:work34# Running Artisan commands within Laravel Sail...5sail artisan queue:work
1# Running Artisan commands locally...2php artisan queue:work34# Running Artisan commands within Laravel Sail...5sail artisan queue:work
執行 PHP 指令
可以使用 php
指令來執行 PHP 指令。當然,這些指令會使用你的專案所設定的 PHP 版本來執行。有關 Laravel Sail 中可用的 PHP 版本,請參考 PHP 版本的說明文件:
1sail php --version23sail php script.php
1sail php --version23sail php script.php
執行 Composer 指令
Composer commands may be executed using the composer
command. Laravel Sail's application container includes a Composer installation:
1sail composer require laravel/sanctum
1sail composer require laravel/sanctum
Installing Composer Dependencies for Existing Applications
若與團隊一起開發專案,則讀者可能不是最初新建 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/php83-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/php83-composer:latest \6 composer install --ignore-platform-reqs
When using the laravelsail/phpXX-composer
image, you should use the same version of PHP that you plan to use for your application (80
, 81
, 82
, or 83
).
執行 Artisan 指令
可使用 `artisan 指令來執行 Laravel Artisan 指令:
1sail artisan queue:work
1sail artisan queue:work
執行 Node 與 NPM 指令
可使用 node
指令來執行 Node 指令,而 npm
指令可用來執行 NPM 指令:
1sail node --version23sail npm run dev
1sail node --version23sail 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_USERNAME
與 DB_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 的網頁管理面板。
Typesense
If you chose to install the Typesense service when installing Sail, your application's docker-compose.yml
file will contain an entry for this lightning fast, open-source search-engine that is natively integrated with Laravel Scout. Once you have started your containers, you may connect to the Typesense instance within your application by setting the following environment variables:
1TYPESENSE_HOST=typesense2TYPESENSE_PORT=81083TYPESENSE_PROTOCOL=http4TYPESENSE_API_KEY=xyz
1TYPESENSE_HOST=typesense2TYPESENSE_PORT=81083TYPESENSE_PROTOCOL=http4TYPESENSE_API_KEY=xyz
From your local machine, you may access Typesense's API via http://localhost:8108
.
檔案儲存
若打算在正式環境使用 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=s32AWS_ACCESS_KEY_ID=sail3AWS_SECRET_ACCESS_KEY=password4AWS_DEFAULT_REGION=us-east-15AWS_BUCKET=local6AWS_ENDPOINT=http://minio:90007AWS_USE_PATH_STYLE_ENDPOINT=true
1FILESYSTEM_DISK=s32AWS_ACCESS_KEY_ID=sail3AWS_SECRET_ACCESS_KEY=password4AWS_DEFAULT_REGION=us-east-15AWS_BUCKET=local6AWS_ENDPOINT=http://minio:90007AWS_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
。
使用 MinIO 時,不支援通過 temporaryUrl
方法來產生臨時儲存空間 URL。
執行測試
Laravel provides amazing testing support out of the box, and you may use Sail's test
command to run your applications feature and unit tests. Any CLI options that are accepted by Pest / PHPUnit may also be passed to the test
command:
1sail test23sail test --group orders
1sail test23sail 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 extra_hosts:4 - 'host.docker.internal:host-gateway'5 volumes:6 - '/dev/shm:/dev/shm'7 networks:8 - sail
1selenium:2 image: 'selenium/standalone-chrome'3 extra_hosts:4 - 'host.docker.internal:host-gateway'5 volumes:6 - '/dev/shm:/dev/shm'7 networks:8 - sail
接著,請確保專案的 docker-compose.yml
檔案中,laravel.test
服務的 depends_on
欄位中有 selenium
:
1depends_on:2 - mysql3 - redis4 - selenium
1depends_on:2 - mysql3 - redis4 - selenium
最後,只要啟動 Sail 並執行 dusk
指令,就能執行 Dusk 的測試套件:
1sail dusk
1sail dusk
Selenium on Apple Silicon
如果你的本機設備為 Apple Silicon 晶片,則 selenium
服務必須使用 seleniarm/standalone-chromium
Image:
1selenium:2 image: 'seleniarm/standalone-chromium'3 extra_hosts:4 - 'host.docker.internal:host-gateway'5 volumes:6 - '/dev/shm:/dev/shm'7 networks:8 - sail
1selenium:2 image: 'seleniarm/standalone-chromium'3 extra_hosts:4 - 'host.docker.internal:host-gateway'5 volumes:6 - '/dev/shm:/dev/shm'7 networks:8 - sail
預覽 E-Mail
Laravel Sail 的預設 docker-compose.yml
檔案中包含了 Mailpit 服務。Mailpit 會在本機開發過程中攔截你的專案所寄出的所有 E-Mail,並提供一個方便的 Web 界面可供你在瀏覽器中預覽這些 E-Mail 訊息。使用 Sail 時,Mailpit 的預設主機名稱為 mailpit
,且可在連接埠 1025 上使用:
1MAIL_HOST=mailpit2MAIL_PORT=10253MAIL_ENCRYPTION=null
1MAIL_HOST=mailpit2MAIL_PORT=10253MAIL_ENCRYPTION=null
When Sail is running, you may access the Mailpit web interface at: http://localhost:8025
Container CLI
有時候,我們可能會需要在專案的 Container 內開啟 Bash 工作階段。可以使用 shell
指令來連線到專案的 Container 中,讓我們能檢視其中的檔案與所安裝的服務,並可在 Container 中執行任意 Shell 指令:
1sail shell23sail root-shell
1sail shell23sail root-shell
若要啟動新的 Laravel Tinker 工作階段,可執行 tinker
指令:
1sail tinker
1sail tinker
PHP 版本
Sail currently supports serving your application via PHP 8.3, 8.2, 8.1, or PHP 8.0. The default PHP version used by Sail is currently PHP 8.3. To change the PHP version that is used to serve your application, you should update the build
definition of the laravel.test
container in your application's docker-compose.yml
file:
1# PHP 8.32context: ./vendor/laravel/sail/runtimes/8.334# PHP 8.25context: ./vendor/laravel/sail/runtimes/8.267# PHP 8.18context: ./vendor/laravel/sail/runtimes/8.1910# PHP 8.011context: ./vendor/laravel/sail/runtimes/8.0
1# PHP 8.32context: ./vendor/laravel/sail/runtimes/8.334# PHP 8.25context: ./vendor/laravel/sail/runtimes/8.267# PHP 8.18context: ./vendor/laravel/sail/runtimes/8.1910# PHP 8.011context: ./vendor/laravel/sail/runtimes/8.0
此外,也可更新 image
的名稱,以反應專案所使用的 PHP 版本。image
名稱的設定在專案的 docker-compose.yml
檔內:
1image: sail-8.2/app
1image: sail-8.2/app
更新好專案的 docker-compose.yml
後,請重新建置 Container Image:
1sail build --no-cache23sail up
1sail build --no-cache23sail up
Node 版本
預設情況下 Sail 會安裝 Node 20。若要更改建置 Image 時使用的 Node 版本,請更新專案中 docker-compose.yml
檔案內 laravel.test
服務的 build.args
定義:
1build:2 args:3 WWWGROUP: '${WWWGROUP}'4 NODE_VERSION: '18'
1build:2 args:3 WWWGROUP: '${WWWGROUP}'4 NODE_VERSION: '18'
更新好專案的 docker-compose.yml
後,請重新建置 Container Image:
1sail build --no-cache23sail up
1sail build --no-cache23sail up
共享網站
有時候,我們需要公開地共享我們的網站,好讓同事能預覽網站,或是能測試專案中的 Webhook 整合。若要共享網站,可以使用 share
指令。執行該指令後,會分配一個隨機的 laravel-sail.site
網址能讓你存取你的網站:
1sail share
1sail share
When sharing your site via the share
command, you should configure your application's trusted proxies using the trustProxies
middleware method in your application's bootstrap/app.php
file. Otherwise, URL generation helpers such as url
and route
will be unable to determine the correct HTTP host that should be used during URL generation:
1->withMiddleware(function (Middleware $middleware) {2 $middleware->trustProxies(at: [3 '*',4 ]);5})
1->withMiddleware(function (Middleware $middleware) {2 $middleware->trustProxies(at: [3 '*',4 ]);5})
若要選擇共享網站時使用的子網域,可在執行 share
指令時提供 subdomain
選項:
1sail share --subdomain=my-sail-site
1sail share --subdomain=my-sail-site
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# Run an Artisan command without Xdebug...2sail artisan migrate34# Run an Artisan command with Xdebug...5sail debug migrate
1# Run an Artisan command without Xdebug...2sail artisan migrate34# Run an Artisan command with Xdebug...5sail debug migrate
使用 Xdebug Browser
若要在通過 Web 瀏覽器瀏覽網站時對網站進行除錯,請依照Xdebug 所提供的說明來在 Web 瀏覽器中啟動 Xdebug 工作階段。
若使用 PhpStorm,請參考 JetBrains 的零設定除錯說明文件。
Laravel Sail 仰賴 artisan serve
來執行網站。只有在 8.53.0 版之後的 Laravel 中,artisan serve
指令才會接受 XDEBUG_CONFIG
與 XDEBUG_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