Laravel多租户部署EB:如何通过子域名识别租户?
基于Elastic Beanstalk实现Laravel Tenancy子域名租户识别
问题背景
已在CloudFlare为租户创建子域名(如netlink.mydomain.com),通过CNAME记录指向Elastic Beanstalk(EB)环境域名;本地通过修改host文件设置127.0.0.1 netlink,可正常访问netlink:8000/api;当前使用Laravel Tenancy v3,需要在EB环境下实现基于子域名的租户识别,想了解具体实现方式,以及是否需要在AWS创建虚拟主机。
是否需要在AWS创建虚拟主机?
不需要单独创建AWS层面的虚拟主机。EB本身支持通过请求的Host头信息识别子域名,只要CloudFlare的CNAME配置正确,EB会将用户请求的原始子域名(如netlink.mydomain.com)完整传递给后端Laravel应用,无需额外在AWS配置虚拟主机。
EB环境下的具体实现步骤
1. 确保EB传递真实Host头
EB默认的Web服务器(Nginx/Apache)配置会保留原始Host头,但需要确认配置无误:
- Nginx环境:登录EB实例查看
/etc/nginx/conf.d/elasticbeanstalk/00_application.conf文件,确保存在proxy_set_header Host $host;配置,这是Laravel能获取真实子域名的关键。 - Apache环境:默认EB的Apache配置已支持传递Host头,无需额外修改。
2. 配置Laravel Tenancy子域名识别
按照Laravel Tenancy v3的规则,配置子域名驱动来识别租户:
- 打开
config/tenancy.php,将识别驱动设为domain,并指定主域名后缀:
'identification' => [ 'drivers' => [ 'domain' => [ 'driver' => 'domain', 'options' => [ 'suffix' => '.mydomain.com', // 替换为你的主域名后缀 ], ], ], 'default' => 'domain', ],
- 确保你的租户模型(如
App\Models\Tenant)包含domain字段,存储对应租户的子域名前缀(如netlink)。
3. 验证租户路由
在routes/tenant.php中添加测试路由,确认租户识别生效:
Route::get('/api', function () { return response()->json([ 'tenant_id' => tenant('id'), 'current_domain' => request()->getHost() ]); });
部署到EB后,访问netlink.mydomain.com/api,应该能返回对应租户的ID和当前访问的子域名。
4. CloudFlare辅助配置(可选)
如果CloudFlare开启了缓存,建议针对API路径设置缓存绕过:在CloudFlare的Page Rules中添加规则,匹配*.mydomain.com/api/*,设置Cache Level: Bypass,避免动态的租户识别逻辑被缓存干扰。
常见问题排查
- Laravel获取不到正确Host头:在Laravel中输出
request()->headers查看Host值,若不正确,检查EB的Web服务器配置,确保proxy_set_header Host $host;(Nginx)配置存在。 - 子域名无法访问:检查CloudFlare的CNAME记录是否生效,EB环境域名是否能正常访问,同时确保子域名已覆盖SSL证书(可使用CloudFlare的Universal SSL免费证书)。
内容的提问来源于stack exchange,提问作者asela daskon
相关产品推荐
相关产品推荐

