Laravel开发推荐php:8.2-cli + nginx:alpine组合,更贴近生产环境;若快速验证可用php:8.2-apache并启用mod_rewrite;需正确挂载.env、配置DB_HOST为服务名、分离Node与PHP容器。

docker-compose.yml 里 PHP 镜像选 php:8.2-apache 还是 php:8.2-cli?
Laravel 开发用 Apache 或 Nginx 更稳妥,php:8.2-cli 没带 Web 服务器,直接跑 php artisan serve 在 Docker 里会卡住或无法被宿主机访问。选 php:8.2-apache 是多数人最省事的起点。
但注意:php:8.2-apache 默认没开 mod_rewrite,Laravel 的路由会 404;php:8.2-cli + Nginx 组合更常见,也更贴近生产环境。
- 开发阶段想快速验证:用
php:8.2-apache,并在 Dockerfile 里加a2enmod rewrite - 长期维护或团队协作:用
php:8.2-cli+ 单独nginx:alpine容器,通过docker-compose.yml网络互通 - 别用
php:8.2-fpm单独跑——它不处理 HTTP 请求,必须配 Web 服务器反代,新手容易漏掉fastcgi_pass配置
Laravel 的 .env 文件为什么在容器里总是不生效?
根本原因就两个:文件没挂载进去,或者挂载后权限不对导致 Laravel 读不到。Docker 默认不会自动同步宿主机的 .env,得手动声明卷(volume)或复制(COPY)。
常见错误是只挂载了 ./app:/var/www/html,却忘了 .env 在项目根目录,不在 app/ 下。另外 Alpine 镜像里 www-data 用户 UID 是 82,而宿主机用户通常是 1000,权限不匹配时 file_get_contents(/var/www/html/.env) 直接失败,但 Laravel 不报错,只默默 fallback 到默认配置。
- 挂载时写全路径:
./.env:/var/www/html/.env:ro(:ro防止容器内误改) - 如果用 COPY,确保
Dockerfile在COPY . /var/www/html前没执行chown -R www-data:www-data /var/www/html,否则.env权限会被覆盖 - 进容器执行
ls -l /var/www/html/.env,确认属主是www-data或至少可读
php artisan migrate 报错 SQLSTATE[HY000] [2002] Connection refused
这是数据库连接失败最典型的提示,90% 是因为 Laravel 没连上 MySQL 容器,而不是密码错了。Docker 里容器间通信靠服务名(docker-compose.yml 里定义的),不是 localhost。
Laravel Cloud(cloud.laravel.com)。此技能用于处理所有 Laravel Cloud 请求,包括搜索和读取数据。只要任务涉及 Laravel Cloud,即使用此技能。
检查 .env 里的 DB_HOST:必须填 MySQL 服务名(比如 mysql),不能填 127.0.0.1 或 localhost——那是指 PHP 容器自己,不是 MySQL 容器。
-
DB_HOST=mysql(对应docker-compose.yml中 MySQL 服务的service name) -
DB_PORT=3306(MySQL 容器暴露的端口,不是宿主机映射的 3307) - PHP 容器启动顺序要等 MySQL 就绪,加
depends_on不够,得用wait-for-it.sh或健康检查脚本 - 临时验证:进 PHP 容器执行
nc -zv mysql 3306,通了再跑 migrate
运行 npm run dev 提示 Cannot find module 'laravel-mix'
因为 Node.js 环境和 PHP 环境通常分两个容器,而 laravel-mix 是开发依赖,只装在 Node 容器里。如果你在 PHP 容器里执行 npm 命令,自然找不到模块。
正确做法是单独起一个 Node 容器,挂载源码,装依赖,构建资源,再把 public/mix-manifest.json 和 public/build/ 同步到 PHP 容器。别图省事把 Node 和 PHP 塞进同一个镜像——体积大、启动慢、职责混乱。
- Node 容器用
node:18-alpine,安装依赖后执行npm run production(非dev,避免生成 source map) - 用
docker cp或多阶段构建把public/*复制进 PHP 镜像,不要在运行时动态编译 - 如果坚持用
npm run dev实时监听,需挂载node_modules并开放端口(如 8080),但热重载在 Docker for Mac/Windows 上有文件系统延迟,体验差
环境变量、网络连通性、容器职责划分——这三个点卡住的人最多,而且错误表现都很“静默”,不像语法错误那样直接报红。调的时候别急着改代码,先确认容器间能不能 ping 通、文件有没有真挂进去、进程是不是在对的容器里跑。










