你好!
我们的技术栈划分了职责:Laravel(DDEV)负责身份验证和用户界面;一个Go 服务提供 API。我们需要让 DDEV 内部的 Laravel 应用能够可靠地调用 Go API。以下是我们的实现方法。
问题
- Laravel 运行在 DDEV 的 Web 容器中。
- Go 服务要么运行在主机上,要么运行在它自己的 Docker Compose 环境中。
- 从 Web 容器内部访问
localhost:8090时,指向的是容器自身,而非主机。 - 使用
host.docker.internal:8090会导致超时(路由或 WSL2 问题),或者要求 Go 应用监听0.0.0.0地址。 - 即使我们收到了响应,也经常遇到401 未授权错误:Laravel 和 Go 之间用于签名请求的共享密钥不一致。
我们希望采用一种可预测的统一配置:将 Laravel 和 Go 放在同一网络中,并在一个地方集中配置共享密钥。
解决方案:将 Go 作为 DDEV 的 Sidecar 服务
我们将 Go 服务(及其 PostgreSQL 数据库)作为自定义 Docker Compose 服务添加到 DDEV 中,使它们与 Web 容器共享同一个 Docker 网络,并可通过服务名称相互通信。
-
自定义 Compose 文件
创建一个类似.ddev/docker-compose.go-api.yaml的文件,其中定义:- go-api-db:为 Go 应用提供 PostgreSQL 数据库(数据存储在命名卷中)。
-
go-api:从你的 Go 项目目录(例如与 Laravel 项目同级的目录)构建镜像;如果使用类似
air的工具,可挂载源码以支持热重载。该服务依赖于go-api-db,并设置APP_HOST=0.0.0.0,以便应用在网络中可被访问。 -
web:扩展 Web 服务,设置你的 API 地址,例如
API_URL=http://go-api:8090,确保 Laravel 始终指向这个 Sidecar 服务。
路径
Compose 文件中的路径是相对于该文件本身的。如果该文件位于.ddev/目录下,而你的 Go 项目与 Laravel 项目处于同级目录,则构建上下文和卷挂载应使用../../your-go-project。共享密钥
双方必须使用相同的值进行请求签名(例如X-Signature)。在 Go 服务中,设置类似SHARED_SECRET: ${SHARED_SECRET:-ddev-sidecar-secret}的环境变量,确保容器始终拥有一个非空的默认值。在 Laravel 的.env文件中,设置相同的值(例如SHARED_SECRET=ddev-sidecar-secret),使 Laravel 使用相同的密钥进行签名。健康检查
为 Go 服务配置一个健康检查,例如访问/health接口,并设置较长的start_period,这样 DDEV 会在首次构建完成后再认为整个服务栈已就绪。
成果
- Laravel 通过服务名称(例如
http://go-api:8090)调用 Sidecar 服务;无需使用主机网络或host.docker.internal。 - 仅需一个
.env文件(Laravel 的)即可同时控制 API 地址和 DDEV 环境下的共享密钥。 -
ddev restart命令可同时启动 Web、数据库以及你的 Sidecar 服务。 - 此模式适用于任何“DDEV 中的 Laravel + 内部 Go(或其他)服务”的场景:添加一个自定义 Compose 文件,将服务加入默认网络,并让 Laravel 指向该服务名称即可。
如果你遇到 401 错误,请仔细检查 Laravel 的 .env 文件和 Go 容器中的共享密钥环境变量是否完全一致。
再见!
免责声明:本文内容来自互联网,该文观点不代表本站观点。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌抄袭侵权/违法违规的内容,请到页面底部单击反馈,一经查实,本站将立刻删除。