我执行此操作是为了使用 terraform 在本地构建 docker 映像。第一次运行成功,但每次尝试
Error: failed to read dockerfile: unexpected EOF
都会失败,除非我完全手动删除 terraform.tfstate
文件。
terraform {
backend "local" {}
required_providers {
docker = {
source = "kreuzwerker/docker"
version = "~>3.0.2"
}
# other providers
}
provider "docker" {
}
resource "docker_image" "dbx_kedro_img" {
name = "docker-build-test:latest"
build {
context = "."
dockerfile = "./Dockerfile"
}
}
我尝试将版本修改为
docker-build-test:latest2
或docker-build-test2:latest
,运行terraform state rm docker_image.dbx_kedro_img
,删除本地docker镜像和容器,但没有成功。唯一有效的方法是手动删除 terraform.tfstate
。欢迎任何想法。
docker rm $(docker ps -aq) # not useful
docker rmi $(docker images -q) -f # idem
terraform state rm docker_image.dbx_kedro_img # idem
我的dockerfile:
# Use a lightweight base image
FROM alpine:latest
#
# Set the command to run when the container starts
CMD ["echo", "Hello, World3!"]
编辑:添加这样的触发器后的相同行为在第一次尝试后失败,即使修改图像名称也是如此。
# not useful
resource "docker_image" "dbx_kedro_img" {
name = "docker-build-test5:latest"
build {
context = "."
dockerfile = "./Dockerfile"
}
triggers = {
always_rebuild = timestamp()
}
}
我查看了提供程序并在调试模式下运行它。我复制的问题是这样的。我创建了一个目录并向其中添加了两个文件。
Dockerfile
和 main.tf
$ ls -1
Dockerfile
main.tf
我运行 terraform apply
Apply complete! Resources: 1 added, 0 changed, 0 destroyed.
我更新了 main.tf 中的标签并再次运行 apply,但出现错误。
╷
│ Error: failed to read dockerfile: unexpected EOF
│
│
│
│ with docker_image.dbx_kedro_img,
│ on main.tf line 10, in resource "docker_image" "dbx_kedro_img":
│ 10: resource "docker_image" "dbx_kedro_img" {
│
然后我设置
TF_LOG=debug
并再次运行应用。值得庆幸的是,提供商已经编写了一些不错的日志记录,因此我们可以看到这里发生了什么。
2025-01-22T22:19:33.805Z [INFO] provider.terraform-provider-docker_v3.0.2.exe: 2025/01/22 22:19:33 [DEBUG] Building docker image: timestamp=2025-01-22T22:19:33.805Z
2025-01-22T22:19:33.805Z [INFO] provider.terraform-provider-docker_v3.0.2.exe: 2025/01/22 22:19:33 [DEBUG] DockerClientVersion: 1.41, minBuildKitDockerVersion: 1.39: timestamp=2025-01-22T22:19:33.805Z
2025-01-22T22:19:33.805Z [INFO] provider.terraform-provider-docker_v3.0.2.exe: 2025/01/22 22:19:33 [DEBUG] Enabling BuildKit: timestamp=2025-01-22T22:19:33.805Z
2025-01-22T22:19:33.806Z [INFO] provider.terraform-provider-docker_v3.0.2.exe: 2025/01/22 22:19:33 [DEBUG] contextDir: timestamp=2025-01-22T22:19:33.806Z
2025-01-22T22:19:33.806Z [INFO] provider.terraform-provider-docker_v3.0.2.exe: 2025/01/22 22:19:33 [DEBUG] relDockerfile: timestamp=2025-01-22T22:19:33.806Z
2025-01-22T22:19:33.806Z [INFO] provider.terraform-provider-docker_v3.0.2.exe: 2025/01/22 22:19:33 [DEBUG] Excludes: []: timestamp=2025-01-22T22:19:33.806Z
2025-01-22T22:19:35.930Z [DEBUG] provider.terraform-provider-docker_v3.0.2.exe: time="2025-01-22T22:19:35Z" level=error msg="Can't add file \\\\?\\C:\\Projects\\GoLand\\playground_terraform\\docker\\terraform.tfstate to tar: read \\\\?\\C:\\Projects\\GoLand\\playground_terraform\\docker\\terraform.tfstate: The process cannot access the file because another process has locked a portion of the file."
2025-01-22T22:19:35.931Z [DEBUG] provider.terraform-provider-docker_v3.0.2.exe: time="2025-01-22T22:19:35Z" level=error msg="Can't add file \\\\?\\C:\\Projects\\GoLand\\playground_terraform\\docker\\terraform.tfstate.backup to tar: archive/tar: missed writing 180 bytes"
2025-01-22T22:19:35.931Z [DEBUG] provider.terraform-provider-docker_v3.0.2.exe: time="2025-01-22T22:19:35Z" level=error msg="Can't close tar writer: archive/tar: missed writing 180 bytes"
2025-01-22T22:19:36.473Z [ERROR] provider.terraform-provider-docker_v3.0.2.exe: Response contains error diagnostic: @caller=github.com/hashicorp/[email protected]/tfprotov5/internal/diag/diagnostics.go:55
diagnostic_summary=
| failed to read dockerfile: unexpected EOF
|
tf_proto_version=5.3 tf_provider_addr=provider @module=sdk.proto diagnostic_detail="" diagnostic_severity=ERROR tf_req_id=f814d0e2-913a-36ef-5484-7c7ba4b34bd5 tf_resource_type=docker_image tf_rpc=ApplyResourceChange timestamp=2025-01-22T22:19:36.473Z
这里发生的事情本质上是状态文件被写入当前目录。与 dockerfile 和上下文相同。因此,当您第二次运行 apply 时,现在状态文件正尝试包含在要发送到 docker 套接字的上下文中。但是,状态文件已被操作系统中的 terraform 进程锁定。所以无法添加到 docker 上下文中。
这会导致在读取 docker 文件时出现关于意外 EOF 的模糊错误。
如果我将 Docker 文件放在子目录中并将上下文和 docker 文件设置到该子目录中,那么一切似乎都可以正常工作。
$ ls -1
docker-build
main.tf
$ ls -1 docker-build/
Dockerfile
resource "docker_image" "dbx_kedro_img" {
name = "docker-build-test:latest2"
build {
context = "./docker-build"
dockerfile = "./Dockerfile"
}
}
在更改标签名称时运行 terraform apply 后,我得到
Apply complete! Resources: 1 added, 0 changed, 1 destroyed.