Open nidotls opened 2 years ago
To be honest, I still don't fully understand your problem regarding watchtower, but I still did some digging and research.
When running docker run --name nginx_test -d nginx:1.23
and docker inspect nginx_test --format '{{.Image}}'
we get sha256:23fc29c9268915db1c2d3007ce77cd2d8b499707538b69ea78a2ae860258fac6
.
That means, docker
automatically converts the nginx:1.23
to an sha and sets the .Image
value, we have no influence on that.
So, although the actual behaviour may seem like a bug, it is the correct behaviour.
Theoretically, when we compose the diff, we could internally pull the sha value of nginx:1
and compare it to the actual value of the running container.
And the value {{.Config.Image}}
is controlled by us, it is currently the same as the value of docker_container.image
.
Could you elaborate again what your ideal solution would look like, so you can use watchtower?
Hello, I just found the ticket and basically I have the same issue. I deployed a container with a static image name, and when I make another plan, terraform compare the sha256 of the image and the name, and consider that the image has changed. So each time, the container is destroyed then deployed. How can we fix that?
@Junkern, reading your paragraph, I understood that Docker transform the name of the image to the hash string. So, I tried to replace the image by the sha256 string.
~ hostname = "5b2166d4c897" -> (known after apply)
~ id = "5b2166d4c897d9dcdbcbbb9547acf0b3f163e0370b7c2d9cb1eccf3276a039fb" -> (known after apply)
~ image = "sha256:d125b701503f942a08f443c7bff54a0600ec327da3ce2fd46086db3d4b5d3ca3" -> "woodpeckerci/woodpecker-server:next-alpine" # forces replacement
~ init = false -> (known after apply)
~ ipc_mode = "private" -> (known after apply)
But the issue is, when I made the change, I discovered that terraform compared the sha256 with the name of the image... So I think that we could find the current name of the image.
# docker_image.woodpecker_server_image must be replaced
-/+ resource "docker_image" "woodpecker_server_image" {
~ id = "sha256:d125b701503f942a08f443c7bff54a0600ec327da3ce2fd46086db3d4b5d3ca3woodpeckerci/woodpecker-server:next-alpine" -> (known after apply)
~ image_id = "sha256:d125b701503f942a08f443c7bff54a0600ec327da3ce2fd46086db3d4b5d3ca3" -> (known after apply)
~ name = "woodpeckerci/woodpecker-server:next-alpine" -> "sha256:d125b701503f942a08f443c7bff54a0600ec327da3ce2fd46086db3d4b5d3ca3" # forces replacement
~ repo_digest = "woodpeckerci/woodpecker-server@sha256:caac5d3e341ebe2bc9e0883c072d27fc3656dd91fbc49c8d8eb304e9593996dd" -> (known after apply)
}
Hello,
Finally a friend of mine gave me the tip: we should not use the name
attribute but the image_id
, then it works. For the original example, it would do:
# use latest v1 image
resource "docker_container" "nginx" {
name = "nginx"
image = docker_image.nginx.image_id
}
Note that even if it works well, when you list running containers on the machine to this the image, you only see hash and not more the name of the image. I don't know exactly if it's a bug or not (that it does not work with .name
) but with image_id
the expected behaviour with Terraform is reached!
A workaround I found is using label
.
data "docker_image" "ubuntu" {
name = "ubuntu:22.04"
}
resource "docker_container" "ubuntu" {
name = "foo"
image = data.docker_image.ubuntu.name
labels = [
{
label = "image.id"
value = data.docker_image.ubuntu.id
}
]
lifecycle {
ignore_changes = [name]
}
}
This way, we can keep the image name as ubuntu:22.04
and the resource will automatically changes if the image name changes in our code (since it will also change image.id and trigger a replacement)
Community Note
Terraform (and docker Provider) Version
Affected Resource(s)
docker_container
docker_image
docker_registry_image
Terraform Configuration Files
Debug Output
https://gist.github.com/thenilsdev/8961e159203c9429601d2eda0aa3f67a
Panic Output
Expected Behaviour
I use watchtower on a staging system. Watchtower checks in regular intervals if all images are up to date. Watchtower does not change
nginx:1.2.2
tonginx:1.2.3
but compares the latestnginx:1
sha256 value with the existing one and updates to it. For watchtower to work, the image must be present in the container (e.g.nginx:1
). In the examples here only the sha256 value is used, which would work but watchtower would not be able to update, since there is not raw image (e.g.nginx:1
).Output with my example code:
When I change
docker_container
image todocker_image.nginx.latest
it outputs the following:So it would be enough if
{{.Config.Image}}
could be set from outside, so watchtower can check this value.Actual Behaviour
Also without changing the registry,
docker_container
tries to changeimage
from the sha256 to the image name every timeSteps to Reproduce
terraform apply
terraform apply
terraform apply
Important Factoids
References