技術 5 分鐘閱讀
用 Docker 打造一致的 Laravel 開發環境
為什麼需要 Docker?
「在我電腦上可以跑啊」大概是工程師最經典的一句話。最近接了一個案子需要和另一位工程師協作,PHP 版本不一致導致各種問題,從那次之後我就決定所有專案都用 Docker。
Laravel Sail vs 自建 Docker
Laravel 官方提供了 Sail,但我更偏好自己寫 docker-compose.yml,因為更靈活、更貼近部署環境。
基本架構
# docker-compose.yml
version: '3.8'
services:
app:
build:
context: .
dockerfile: Dockerfile
container_name: laravel_app
volumes:
- .:/var/www/html
ports:
- "8000:8000"
depends_on:
- mysql
- redis
networks:
- laravel
mysql:
image: mysql:8.0
container_name: laravel_mysql
environment:
MYSQL_ROOT_PASSWORD: secret
MYSQL_DATABASE: laravel
MYSQL_USER: laravel
MYSQL_PASSWORD: secret
ports:
- "3306:3306"
volumes:
- mysql_data:/var/lib/mysql
networks:
- laravel
redis:
image: redis:alpine
container_name: laravel_redis
ports:
- "6379:6379"
networks:
- laravel
mailpit:
image: axllent/mailpit
container_name: laravel_mailpit
ports:
- "8025:8025"
- "1025:1025"
networks:
- laravel
networks:
laravel:
volumes:
mysql_data:
Dockerfile
FROM php:8.3-fpm
RUN apt-get update && apt-get install -y \
git curl zip unzip libpng-dev libonig-dev libxml2-dev \
&& docker-php-ext-install pdo_mysql mbstring exif pcntl bcmath gd
COPY --from=composer:latest /usr/bin/composer /usr/bin/composer
WORKDIR /var/www/html
COPY . .
RUN composer install --optimize-autoloader
CMD ["php", "artisan", "serve", "--host=0.0.0.0"]
常用指令
# 啟動所有服務
docker compose up -d
# 執行 artisan 指令
docker compose exec app php artisan migrate
# 進入容器
docker compose exec app bash
# 查看日誌
docker compose logs -f app
# 重建 image
docker compose build --no-cache
.env 設定調整
DB_CONNECTION=mysql
DB_HOST=mysql
DB_PORT=3306
DB_DATABASE=laravel
DB_USERNAME=laravel
DB_PASSWORD=secret
REDIS_HOST=redis
MAIL_MAILER=smtp
MAIL_HOST=mailpit
MAIL_PORT=1025
注意 DB_HOST 和 REDIS_HOST 要填 Docker 的 service 名稱,不是 localhost。
搭配 Seeder 初始化
容器啟動後可以搭配 Seeder 快速填入測試資料:
docker compose exec app php artisan migrate:fresh --seed
部署考量
開發環境的 Docker 設定和正式環境會有些不同。之後可以搭配 GitHub Actions 做到自動化部署。
小結
Docker 的初始設定需要花一些時間,但一旦設好就能確保每個人的環境完全一致。特別是接案經常需要同時維護多個專案時,Docker 能讓你快速切換而不會互相干擾。
如果你需要類似的系統,歡迎聯繫討論。
#Docker #Laravel