如何让Laravel DOMPDF在Laravel Sail环境中正常工作?
问题原因与解决方案
核心原因
- Docker容器网络隔离:Sail基于Docker运行,Laravel应用和DOMPDF都在容器内部。当你设置
APP_URL=http://localhost时,容器内的DOMPDF会尝试访问容器自身的localhost,而非宿主机的localhost,自然无法获取到静态资源。而Lando的网络模式直接共享宿主机网络或使用本地域名解析,不存在这个隔离问题。 - 静态资源路径解析差异:Vite编译后的资源路径依赖
APP_URL生成,容器内无法通过宿主机的localhostURL访问到编译后的静态文件(除非做了特殊网络映射)。
具体解决方案
方案1:调整APP_URL为容器内部可访问地址
Sail默认的容器服务名为laravel.test,你可以:
- 修改
.env中的APP_URL为:APP_URL=http://laravel.test - 在宿主机的
hosts文件(Windows为C:\Windows\System32\drivers\etc\hosts,Mac/Linux为/etc/hosts)添加一行:127.0.0.1 laravel.test
这样容器内的DOMPDF访问http://laravel.test时,Docker内部DNS会直接解析到Laravel容器,就能正常获取静态资源。
方案2:直接使用本地文件路径(推荐)
DOMPDF支持通过file://协议读取本地文件,避免HTTP请求带来的网络问题:
- CSS资源:借助Vite的manifest文件获取编译后的哈希文件名,在控制器中传递正确的本地路径:
$manifest = json_decode(file_get_contents(public_path('build/manifest.json')), true); $cssPath = public_path('build/' . $manifest['resources/css/app.css']['file']); return view('dispatch-sheet', compact('cssPath'));
在模板中引用:
<link rel="stylesheet" href="file://{{ $cssPath }}">
- 图片资源:直接使用
public_path()生成本地路径:
<img src="file://{{ public_path('images/your-logo.png') }}" alt="Logo">
方案3:配置Vite生成相对路径资源
修改vite.config.js,设置base为相对路径,让Vite编译后的资源引用不依赖APP_URL:
import { defineConfig } from 'vite'; import laravel from 'laravel-vite-plugin'; export default defineConfig({ base: './', plugins: [ laravel({ input: [ 'resources/css/app.css', 'resources/js/app.js', ], refresh: true, }), ], });
执行npm run build重新编译资源,同时确保DOMPDF的chroot配置指向public目录(在config/dompdf.php中设置):
'chroot' => public_path(),
额外检查项
- 确认容器内的
allow_url_fopen已开启(Sail默认开启,可通过php -i | grep allow_url_fopen验证) - 确保静态文件的权限正确,容器内的Laravel进程能读取
public/build和public/images目录
内容的提问来源于stack exchange,提问作者Sturm
相关产品推荐
相关产品推荐

