Back

Laravel 環境設定

2021.08.29 更新: 根據討論,移除 Docker Compose 上的 version: '3'。自 Docker Compose 1.27 開始版本為可選值,而官方也是推薦這麼做

概念

  • Windows, Linux, macOS 通用
  • 輕量化、啟動速度快
  • 能夠整合開發工具

實作

建立 docker-compose.yaml

在 Laravel 專案下建立 docker/develop/docker-compose.yaml

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
# ./docker/develop/docker-compose.yaml
networks:
  laravel:
    driver: bridge

services:
  laravel:
    build:
      context: .
    volumes:
      - ../../:/app
    ports:
      - 8000:8000
    networks: [ "laravel" ]
    command: [ "php", "artisan", "serve", "--host=0.0.0.0" ]
    healthcheck:
      test: [ "CMD", "curl", "localhost:8000" ]
      retries: 3
      timeout: 5s
  database:
    image: 'postgres:latest'
    environment:
      POSTGRES_DB: laravel
      POSTGRES_UESR: laravel
      POSTGRES_PASSWORD: password
    ports:
      - 5432:5432
    networks: [ "laravel" ]
    healthcheck:
      test: [ "CMD", "pg_isready", "-q", "-d", "laravel", "-U", "laravel" ]
      retries: 3
      timeout: 5s
  redis:
    image: 'redis:alpine'
    ports:
      - 6379:6379
    networks: [ "laravel" ]
    healthcheck:
      test: [ "CMD", "redis-cli", "ping" ]
    

可以自由增加、減少或變更所需的服務,只需要在這個檔案上進行修改即可。

例如,想將 PostgreSQL 改為 MySQL:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
# ...
  database:
    image: 'mysql:8'
    environment:
      MYSQL_ROOT_PASSWORD: password
      MYSQL_DATABASE: laravel
      MYSQL_USER: laravel
      MYSQL_PASSWORD: password
    ports:
      - 3306:3306
    networks: [ "laravel" ]
    healthcheck:
      test: [ "CMD", "mysqladmin", "ping", "-plaravel" ]
      retries: 3
      timeout: 5s
# ...

建立 Dockerfile 及 Entrypoint

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
# ./docker/develop/entrypoint.sh
#!/bin/sh

if [ ! -d "/app/vendor" ]; then
    composer install
fi

php artisan storage:link
php artisan migrate

exec "[email protected]"

記得將 ./docker/develop/entrypoint.sh 設為可執行

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
# ./docker/develop/Dockerfile
FROM php:alpine

EXPOSE 8000
WORKDIR /app

RUN apk update && apk upgrade && apk add curl postgres-dev ${PHPIZE_DEPS} composer && \
    docker-php-ext-install bcmath opcache pdo_pgsql && \
    pecl install redis && docker-php-ext-enable redis

ENTRYPOINT ["/app/docker/develop/entrypoint.sh"]

可以在 Dockerfile 中安裝任何所需要的套件或擴充元件,例如用 pecl install swoole 加入 Swoole extension。

使用

本地開發(Local)

1
2
3
4
docker compose -p laravel -f docker/develop/docker-compose.yaml up -d database redis
php artisan storage:link
php artisan migrate
php artisan serve

對於本地開發,會推薦開發者應該維護一個 PHP 執行環境,並且以原生的方式執行 PHP Built-in Web Server

  • .env 中的 DB_HOSTREDIS_HOST 應該設為 127.0.0.1
  • 可以使用任何 Redis 及 DB 客戶端進行連線操作
  • 可以使用本地端的 Debugger(如 XDebug)

註:事實上在容器內的開發也可以使用 Debugger,但是它的連線設定會複雜得多

容器開發(Develop)

1
docker compose -p laravel -f docker/develop/docker-compose.yaml up -d

考量到有時候 Laravel 會作為 API Server,而前端開發者並不一定會有 PHP 執行環境,我們依賴 Dockerfileentrypoint.sh 構建一個環境。

  • .env 中的 DB_HOST 應該設為 database(與 docker-compose.yaml 中的服務名稱相同)
  • .env 中的 REDIS_HOST 應該設為 redis(與 docker-compose.yaml 中的服務名稱相同)
  • 可以使用任何 Redis 及 DB 客戶端進行連線操作

比較

Laravel Homestead

Laravel Homestead 是以 Vagrant 為底層的開發環境,它提供了 Ubuntu 20.04 的作業系統與許多開發時常用的工具。

缺點是它基於虛擬機(Virtual Machine, VM)以致於啟動速度較慢,首次使用時也需要從網路上下載較多的資料(Vagrant Box)。

註:Vagrant 也有提供 Docker 作為其 Provider,但是在 Homestead 的官方文件上並無相關說明

Laravel Valet

Laravel Valet 是結合 Homebrew 專為 macOS 所設計的開發環境,它的優點是使用自行安裝的 PHP 與其它附屬軟體(如 DB),屬於最輕量的解決方案。

缺點是它需要自行安裝附屬軟體,且過多的軟體可能導致系統內變得混亂而難以管理。

註:社群有推出非官方的 Valet LinuxValet Linux+ 作為 Linux 的解決方案,但支援速度與完整性較低

Laravel Sail

Laravel Sail 是結合 Docker 的開發環境,實際上本文的開發環境有許多設計是承襲於此,它擁有較高的執行效率、也不會汙染作業系統內的軟體。

缺點是它本質上屬於 PHP 的軟體生態系(composer),用戶安裝時仍然必須使用 composer;另外它的設計上使用 ubuntu 作為其 Base Image,這讓它構建出來的 Docker Image 較為肥胖。

Laradock

Laradock 是目前最完整的 Docker 與 Laravel 解決方案,它的高度客製化能夠讓開發者設定所需的附屬軟體及執行環境,同時也不依賴 PHP 軟體生態系。

缺點是它的設定較複雜,難以獲得開箱即用的開發體驗,然而在服務的構建上不失為一種良好的參考範本。

結論

本篇所建構的 Laravel 開發環境有很大一部份承襲自 Laravel Sail, Laravel Valet 及 Laradock 的實作與思想,這同時也是我個人與為公司內部合作時所設計的開發環境。

這個開發環境事實上經過多次的演變,從 Homestead 到 Valet,再到 Sail,基本上每一次官方推出新的解決方案時我都會優先嘗試。

然而,可能是考量到使用者的方便性,官方幾乎都以 PHP 軟體生態系本位出發,並且優先考量 macOS 及 Ubuntu。(我仍然無法理解在 Docker 中仍然堅持使用 Ubuntu 是有什麼毛病…)

Built with Hugo
Theme Stack designed by Jimmy