I’m trying to start a docker container in my app written in Golang.
In this question, thanks for the answers, I know how to create my customized network with
resp, err := dn.cl.NetworkCreate(context.Background(), "mynet", types.NetworkCreate{
Driver: "bridge",
IPAM: &network.IPAM{
Config: []network.IPAMConfig{{
Subnet: "128.0.1.9/16",
}},
},
})
They should be the equivalent of docker network create -d bridge --subnet=128.0.1.9/16 mynet
And I’d like to use the golang SDK to do the equivalent of
docker run -d
--name=mydocker
--ip=128.0.1.9
--hostname=roach1
--net=mynet
-p 1234:1234 -p 8080:8080
myimage/myimage-ci:latest
And I’m writing this
containerConfig := container.Config{
Hostname: containerName,
Image: imageName,
Env: envSetting,
ExposedPorts: nat.PortSet{"8080": struct{}{}, "1234": struct{}{}},
Cmd: cmd,
}
hostConfig := container.HostConfig{
Binds: volSetting,
PortBindings: map[nat.Port][]nat.PortBinding{
nat.Port("8080"): {{HostIP: "128.0.1.9", HostPort: "8080"}},
nat.Port("1234"): {{HostIP: "128.0.1.9", HostPort: "1234"}},
},
}
resp, err := dn.cl.ContainerCreate(
ctx,
&containerConfig,
&hostConfig,
nil,
nil,
containerName,
)
But it’s not working. I got the following error:
cannot start container: Error response from daemon: Ports are not available: exposing port TCP 128.0.1.9:1234 -> 0.0.0.0:0: listen tcp 128.0.1.9:1234: bind: can't assign requested address
I also inspected the network I created
[
{
"Name": "mynet",
"Id": "d009c6f68492abfa0257c2980dcfaaa425338740327ef811b209xxxxxxxxx",
"Created": "2022-08-1T16:42:14.880121815Z",
"Scope": "local",
"Driver": "bridge",
"EnableIPv6": false,
"IPAM": {
"Driver": "default",
"Options": null,
"Config": [
{
"Subnet": "128.0.1.9/16"
}
]
},
"Internal": false,
"Attachable": false,
"Ingress": false,
"ConfigFrom": {
"Network": ""
},
"ConfigOnly": false,
"Containers": {},
"Options": {},
"Labels": {}
}
]
I suspect it’s because I didn’t specify that the container should join the mynet
network. But how to do that with the SDK?
2
Answers
The
HostIP
fields specify an IP address on the host machine to use for publishing ports. That has to be one of the IP addresses configured on the host system, you can’t make up an address there. The most common thing you’d set it to is"127.0.0.1"
, if you want a published port to be accessible from the host system from outside of Docker space but not from other hosts. This is equivalent to the occasionally-used IP address part of thedocker run -p
option, likedocker run -p 127.0.0.1:8080:8080
.The immediate cause of your error message is that the
HostIP
address isn’t one configured on the host, and the easiest solution is to just delete that option (it will default to"0.0.0.0"
).Separately, the fourth parameter to
(*Client).ContainerCreate()
is anetwork.NetworkingConfig
structure. You should be able to use this to attach the container to your custom networkThe
EndpointSettings
includes anEndpointIPAMConfig
structure. If you needed to override Docker’s setup and manually assign IP addresses here, you could. However, since the Docker-internal IP addresses aren’t especially useful, I’d let Docker pick an address for you (and, similarly, I’d skip thedocker run --ip
option).You can specify an previously created network by just using the name in the
NetworkID
field of theEndpointSettings
.For instance, to create a kafka container and add the
orchestration
network: