Laravel Sail 是 Laravel 官方基于 Docker 的轻量级本地开发环境工具,封装了 sail 命令与预配置 docker-compose.yml,开箱即用,解决版本统一、权限同步、命令转发等痛点;适用于单项目快速启动,不适用于多项目共享服务、深度定制或生产部署。

Laravel Sail 是 Laravel 官方提供的、基于 Docker 的轻量级本地开发环境封装工具,它不是独立的 Docker 编排系统,而是 sail 命令行脚本 + 预配置的 docker-compose.yml 的组合。你不需要手写复杂 Dockerfile 或反复调试网络、卷挂载,开箱即可运行 Laravel 项目。
为什么不用直接写 docker-compose.yml?
直接写 docker-compose.yml 当然可以,但 Laravel Sail 解决了几个高频痛点:
- 统一管理 PHP 版本、MySQL/PostgreSQL/Redis 等服务版本与默认配置(比如 MySQL 默认启用
utf8mb4_0900_as_cs排序规则) - 自动挂载当前项目目录到容器内
/var/www/html,且保持用户 UID/GID 一致,避免文件权限混乱(www-data写不了storage/) -
sail artisan、sail npm run dev等命令自动转发到对应容器,无需手动docker exec -it - 一键启停:
sail up -d/sail down,比记一堆docker-compose参数更直观
如何初始化并启动 Sail?
前提是已安装 Docker Desktop(或 Linux 上的 Docker Engine + docker-compose v2.2+),且项目根目录下已有 composer.json(Laravel 9+ 新项目默认带 Sail)。
若项目未初始化 Sail:
php artisan sail:install
该命令会:
- 生成
docker-compose.yml(含laravel.test、mysql、redis等服务) - 创建
./vendor/bin/sail可执行脚本(Linux/macOS)或sail.bat(Windows) - 提示你选择数据库类型和是否启用 Selenium、Meilisearch 等可选服务
然后运行:
./vendor/bin/sail up -d
首次启动会拉取镜像(如 laravelsail/php82-composer),耗时较长;后续启动很快。
常见问题:访问不了 http://localhost 或 artisan 命令报错
典型现象包括:
- 浏览器打开
http://localhost显示 “This site can’t be reached” -
sail artisan migrate报错SQLSTATE[HY000] [2002] Connection refused -
sail npm run dev启动后热更新不生效,或 WebSocket 连接失败
原因和对策:
-
docker-compose.yml中laravel.test的ports没暴露 80/443:确认有- '80:80'或- '127.0.0.1:80:80',不要写成- '8080:80'却还用localhost访问 - MySQL 容器没就绪就执行迁移:加
--wait或等sail ps显示所有状态为Up再操作;也可在.env中设DB_HOST=mysql(非127.0.0.1) - NPM 开发服务器监听
localhost而非0.0.0.0:修改package.json中"dev": "vite --host"或"dev": "mix --host 0.0.0.0" - Windows 上 WSL2 与 Docker Desktop 网络隔离:关闭 WSL2 后重开终端,或改用
sail shell进入容器内部调试
什么时候不该用 Sail?
Sail 是为“单项目快速启动”设计的,不适合以下场景:
- 需要多项目共用一套 MySQL/Redis(Sail 每个项目都起独立容器,端口易冲突)
- 要深度定制 PHP 扩展(如
grpc、sqlsrv),Sail 提供的镜像不含这些,需自己构建基础镜像 - 生产环境部署参考——Sail 的镜像是开发向的(含 Xdebug、Composer、Node.js),体积大、不安全,不能直接用于线上
- CI/CD 流水线中复用——Sail 脚本依赖宿主机的
docker和docker-compose,CI 环境通常用更精简的纯docker-compose或 GitHub Actions 自定义 runner
真正麻烦的从来不是启动容器,而是搞清哪个服务该连哪个 host、哪个端口、谁先启动谁后启动、文件权限怎么同步——Sail 把这些默认值固化下来,省掉前 30 分钟踩坑时间。但一旦需求超出它的预设边界,就得切回原生 Docker 工作流。










