如何程序化在Heroku部署Laravel应用、关联Git仓库及配置Cloudflare DNS
实现方案总览
你需要分别对接Heroku和Cloudflare的官方API,在Laravel的用户创建事件触发时执行对应的自动化逻辑,整体流程拆分为前置准备、核心逻辑实现两个部分。
前置准备
- 先获取两个平台的API凭证:
- Heroku:在Heroku账号设置中生成账户API密钥,同时提前准备好你要关联的公共/私有Git仓库地址
- Cloudflare:生成Cloudflare全局API密钥,同时记录你要绑定的根域名对应的Cloudflare Zone ID
- 在Laravel项目的
.env文件中配置这几个敏感凭证,不要硬编码在代码里:HEROKU_API_KEY=你的Heroku密钥 HEROKU_TEAM_ID=可选,如果是团队账号需要填写 CLOUDFLARE_API_KEY=你的Cloudflare密钥 CLOUDFLARE_EMAIL=你的Cloudflare登录邮箱 CLOUDFLARE_ROOT_ZONE_ID=根域名对应的Zone ID APP_GIT_REPO_URL=你要关联的代码仓库地址 - 直接用Laravel自带的Http客户端调用API即可,不需要额外安装多余依赖。
核心逻辑实现
第一步:绑定Laravel用户创建事件触发器
首先生成用户创建的事件和监听器,在app/Providers/EventServiceProvider.php中注册关联:
protected $listen = [ 'App\Events\UserCreated' => [ 'App\Listeners\ProvisionUserHerokuApp', ], ];
然后在你的用户创建逻辑(比如注册控制器、用户创建Service)中,用户保存成功后触发事件:
event(new UserCreated($user));
第二步:实现Heroku应用创建+关联仓库逻辑
在监听器ProvisionUserHerokuApp中首先调用Heroku API创建应用,你可以自定义应用名称为比如用户唯一标识-你的应用名:
// 创建Heroku应用 $herokuAppResponse = Http::withToken(config('env.heroku_api_key')) ->post('https://api.heroku.com/apps', [ 'headers' => [ 'Accept' => 'application/vnd.heroku+json; version=3' ], 'json' => [ 'name' => $user->username . '-myapp', 'region' => 'us', // 可替换为你需要的区域 'team' => config('env.heroku_team_id') // 团队账号需要传 ] ]); $herokuAppId = $herokuAppResponse->json('id'); $herokuAppDomain = $herokuAppResponse->json('web_url'); // 关联Git仓库,设置自动部署 Http::withToken(config('env.heroku_api_key')) ->post("https://api.heroku.com/apps/{$herokuAppId}/builds", [ 'headers' => [ 'Accept' => 'application/vnd.heroku+json; version=3' ], 'json' => [ 'source_blob' => [ 'url' => config('env.app_git_repo_url') . '/archive/refs/heads/main.tar.gz', // 替换为你要部署的分支压缩包地址 'version' => 'main' ] ] ]);
注意:如果是私有仓库,你需要在Git地址中带上有权限的访问令牌,保证Heroku可以拉取代码
第三步:实现Cloudflare DNS配置逻辑
拿到Heroku应用的域名后,调用Cloudflare API创建DNS记录,比如你要给每个用户分配{用户名}.你的根域名.com的域名:
Http::withHeaders([ 'X-Auth-Email' => config('env.cloudflare_email'), 'X-Auth-Key' => config('env.cloudflare_api_key'), 'Content-Type' => 'application/json' ])->post("https://api.cloudflare.com/client/v4/zones/" . config('env.cloudflare_root_zone_id') . "/dns_records", [ 'type' => 'CNAME', 'name' => $user->username . '.yourdomain.com', 'content' => parse_url($herokuAppDomain, PHP_URL_HOST), 'ttl' => 1, // 自动TTL 'proxied' => true // 开启Cloudflare代理,不需要的话设为false ]);
如果需要自定义nameserver而不是CNAME记录,把上面的type改成NS,content填你要指向的nameserver地址即可
第四步:异常处理和状态回调
- 建议把整个置备逻辑放到Laravel队列中异步执行,避免用户创建请求卡住超时
- 给用户表加
app_provision_status字段,记录置备状态:待处理、成功、失败,失败的话可以记录错误信息方便排查 - 置备完成后可以给用户发通知告知应用地址
可选优化项
- 提前准备好Heroku应用的环境变量模板,创建应用时自动把用户专属的配置(比如数据库连接、用户ID)注入到Heroku应用的环境变量中
- 配置Heroku应用的自动扩容规则、日志收集规则
- 添加置备失败自动重试逻辑,避免API调用临时失败导致的置备失败
内容的提问来源于stack exchange,提问作者Lusit
相关产品推荐
相关产品推荐

