laravel 8 在 mac 上用 docker 开发首选 sail,但必须先确保 docker desktop 已启动、项目含 docker-compose.yml 和 vendor/bin/sail,否则报“command 'sail' is not defined”;db_host 必须设为 mysql(非 localhost),并配置国内镜像加速器防拉取卡死。

直接上结论:Laravel 8 在 Mac 上用 Docker 开发,首选 Sail,但前提是项目已集成 Sail 脚本和 docker-compose.yml;否则执行 sail 命令会报错 Command "sail" is not defined。别硬套教程跑 php artisan sail:install——它只对新项目或未初始化 Sail 的项目有效。
确认 Docker Desktop 和 Sail 是否就绪
这是最常卡住的第一步。Sail 不是独立工具,它依赖宿主机的 Docker 运行时和项目内的配置文件。
- 运行
docker --version和docker compose version,两个命令都必须有输出(注意是docker compose,不是旧版docker-compose) - 检查项目根目录是否存在
docker-compose.yml—— Laravel 8+ 默认自带,老项目可能要先跑php artisan sail:install - 检查
vendor/bin/sail是否存在;不存在说明没装laravel/sail包,需补composer require laravel/sail --dev - 国内用户务必提前配置 Docker 镜像加速器(如
https://hub-mirror.c.163.com),否则./vendor/bin/sail up会卡在拉取mysql或nginx镜像阶段
启动前必须改的 .env 配置项
Laravel 容器内连不上数据库,90% 是因为 .env 里填了 DB_HOST=localhost 或 127.0.0.1 —— 这在容器里指向的是 PHP 自己,不是 MySQL 容器。
MiniMax 图片理解 + 网络搜索 MCP 工具。适配 Docker 环境(极空间等),支持图片 OCR 识别、图像内容理解、网络搜索。API Key 安全存储在本地 credentials 文件,不暴露在代码中。
-
DB_HOST=mysql(对应docker-compose.yml中 service 名为mysql) -
DB_PORT=3306(不是宿主机映射的端口,比如3307) -
REDIS_HOST=redis(如果启用了 Redis 服务) -
APP_URL=http://localhost:8080(Sail 默认映射 Nginx 到宿主机8080端口) - 确保
.env文件被正确挂载:Sail 默认通过 volume 把项目根目录映射进容器,所以.env必须放在项目根目录,不能只在app/下
常见启动失败现象与定位方式
别盲目重启 sail up,先看日志源头在哪:
-
php artisan migrate报SQLSTATE[HY000] [2002] Connection refused→ 检查DB_HOST和容器网络是否通,进 PHP 容器执行ping mysql或nc -zv mysql 3306 - 浏览器打开
http://localhost:8080显示 502 Bad Gateway → Nginx 容器启动了,但连不上 PHP-FPM,检查docker-compose.yml中nginx服务的fastcgi_pass是否指向php-fpm:9000(Sail 默认用laravel.test域名,Nginx 配置由 Sail 自动生成) - 容器反复重启 → 查
docker logs -f <container-name></container-name>,重点看 MySQL 初始化日志里有没有mysqld: ready for connections,没这句说明 DB 没真正就绪,PHP 容器就贸然执行迁移会失败 - 执行
sail artisan tinker报错Class 'App\Console\Commands\...' not found→ 进容器后先运行composer install,Sail 不自动装依赖
多版本 Laravel 项目共存时的关键点
如果你同时维护 Laravel 6(需 PHP 7.2)和 Laravel 9(需 PHP 8.1),Sail 默认配置不支持混用 —— 它只读一个 docker-compose.yml。
- 不要试图在一个项目里改
docker-compose.yml切换 PHP 版本,容易污染配置;每个项目应保持独立的docker-compose.yml和Dockerfile - 若需复用镜像,可把 PHP 构建逻辑抽成
Dockerfile.php72和Dockerfile.php81,再在各自docker-compose.yml中指定build: { context: ., dockerfile: Dockerfile.php72 } - Nginx 配置按域名隔离:比如
sso.example.com.conf和app.example.com.conf分别指向不同 PHP 容器,靠upstream名区分 - MySQL 数据目录必须分开挂载(如
./mariadb-data-sso:/var/lib/mysql),否则多个项目共用一套数据会冲突
最容易被忽略的是权限问题:Alpine 镜像中 www-data 用户 UID 是 82,而 Mac 宿主机用户通常是 501,导致容器内读不到 .env 却不报错,只 fallback 到默认配置。进容器执行 ls -l .env 看属主,必要时加 :ro 挂载或在 Dockerfile 里显式 chown。










