hashicorp/terraform-provider-docker

Ports are published even no `external`

Closed this issue · 3 comments

trung commented

Terraform Version

› terraform --version                                                                                                                                                                                         
Terraform v0.12.24
+ provider.docker v2.7.0

Affected Resource(s)

  • docker_container

Terraform Configuration Files

resource "docker_container" "test" {
  image = "nginx:latest"
  name = "test-container"
  must_run = true
  ports {
    internal = 3000
  }
}

Expected Behavior

Port 3000 is exposed internally and not published to host

Actual Behavior

Port 3000 is published to host via random port 32768

› docker ps                                                                                                                                                                                                   
CONTAINER ID        IMAGE               COMMAND                  CREATED             STATUS              PORTS                               NAMES
775de90f3957        nginx:latest        "nginx -g 'daemon of…"   2 seconds ago       Up 1 second         80/tcp, 127.0.0.1:32768->3000/tcp   test-container

Hey, this was a desired feature of #102. When I run docker run -d -p3000 nginx locally, I also get a random port exposed. IMHO this is the behavior of the cli as well:

$ docker run -d -p3000 nginx

CONTAINER ID        IMAGE               COMMAND                  CREATED             STATUS              PORTS                             NAMES
bac7797bfe6e        nginx               "nginx -g 'daemon of…"   2 seconds ago       Up 1 second         80/tcp, 0.0.0.0:32770->3000/tcp   optimistic_shaw
trung commented

Thanks for getting back. docker run has 2 options:

  • --expose: this allows container to expose ports without publishing to host
  • --publish or -p: this allows container to publish ports to host

The current behavior of ports block seems for the later. Is there a way to achieve the former?

It appears that the critical bit of code is here: https://github.com/terraform-providers/terraform-provider-docker/blob/ee53b9e8ae42f554338ba9ee860f3ced00be3c23/docker/resource_docker_container_funcs.go#L913-L934

They produce the required mappings as specified here
and here
with the structures defined here.

What I think needs to happen is to wrap:
https://github.com/terraform-providers/terraform-provider-docker/blob/ee53b9e8ae42f554338ba9ee860f3ced00be3c23/docker/resource_docker_container_funcs.go#L933
in a conditional if (extOk || ipOk) {

I think the intended logic was that if the external port is specified, it is published, otherwise it is internally exposed. That is not occurring, without the proposed conditional it will expose a random port. Adding the proposed conditional will allow a random port to be assigned by specifying external = 0 as is consistent with here while enabling the intended logic of omitting external.