我有一个 terraform 项目,我想在其中使用
"kreuzwerker/docker" 3.0.2
作为 terraform 提供程序来启动我的环境。在我正在启动的 docker 容器内,我遇到了一个问题,即我的后端容器没有等待我的 postgresql 容器准备好接受连接。我怎样才能正确地实现这一目标?
database
resource "docker_container" "postgres" {
provider = docker.database_server
name = "postgres"
image = docker_image.postgres.image_id
env = [
"POSTGRES_USER=postgres",
"POSTGRES_PASSWORD=postgres",
"POSTGRES_DB=postgres"
]
ports {
ip = <some_ip>
external = 5432
internal = 5432
}
}
backend
resource "docker_container" "backend" {
provider = docker.backend_server
name = "backend"
image = docker_image.backend.image_id
}
有了问题中所示的这两个资源,Terraform 无法知道
docker_container.backend
取决于 docker_container.postgres
。
尽管 Terraform 通常会根据引用自动推断依赖关系,但在这种情况下,
docker_container.backend
似乎没有任何充分的理由使用 docker_container.postgres
的任何属性,因此这是您可以使用的“隐藏依赖关系”的示例可以使用 depends_on
元参数来指定。
resource "docker_container" "postgres" {
provider = docker.database_server
name = "postgres"
image = docker_image.postgres.image_id
env = [
"POSTGRES_USER=postgres",
"POSTGRES_PASSWORD=postgres",
"POSTGRES_DB=postgres"
]
ports {
ip = "..."
external = 5432
internal = 5432
}
}
resource "docker_container" "backend" {
depends_on = [docker_container.postgres]
provider = docker.backend_server
name = "backend"
image = docker_image.backend.image_id
}
但是,添加
depends_on
仅告诉 Terraform 它应该等到 Docker 提供商报告它已完成创建 docker_container.postgres
。如果提供商在 Postgres 服务器完成启动之前报告成功,那么您可能仍然遇到类似的问题。 Terraform 无法“查看”您的 Docker 容器,因此它必须依赖 Docker 提供程序来报告容器何时准备就绪。
我对这个提供程序特别不熟悉,但它的文档暗示
must_run
参数(默认情况下为 true
)会导致提供程序检查容器是否正在运行,这可能就足够了,但我不确定。
如果可能,为了稳健性,我建议将软件设计为能够适应连接问题。
例如,您称为“后端”的容器理想情况下可以容忍 Postgres 服务器不可用,并礼貌地重试连接,直到成功为止。如果您出于任何原因需要稍后重新启动 Postgres 容器,这也会很有帮助,以便后端在再次开始运行后不久会自动重新连接。