I'm trying to setup some very simple networking between a pair of Docker containers and so far all the documentation I've seen is far more complex than for what I am trying to do.
My use case is simple:
Container 1 is already running and is listening on port 28016
Container 2 will start after container 1 and needs to connect to container 1 on port 28016.
I am aware I can set this up via Docker-Compose with ease, however Container 1 is long-lived and for this use case, I do not want to shut it down. Container 2 needs to start and automatically connect to container 1 via port 28016. Also, both containers are running on the same machine. I cannot figure out how to do this.
I've exposed 28016 in Container 1's dockerfile, and I'm running it with -p 28016:28016. What do I need to do for Container 2 to connect to Container 1?
There are a few ways of solving this. Most don't require you to publish the ports.
Using a user defined network
If you start your long-running container in a user-defined network, because then docker will handle
docker network create service-network
docker run --net=service-network --name Container1 service-image
If you then start your ephemeral container in the same network, it will be able to refer to the long-running container by name. E.g:
docker run --name Container2 --net=service-network ephemeral-image
Using the existing container network namespace
You can just run the ephemeral container inside the network namespace of the long running container:
docker run --name Container2 --net=container:Container1 ephemeral-image
In this case, the service would be available via localhost:28016.
Accessing the service on the host
Since you've published the service on the host with -p 28016:28016, you can refer to that access using the address of the host, which from inside the container is going to be the default gateway. You can get that with something like:
address=$(ip route | awk '$1 == "default" {print $3}')
And your service would be available on ${address}:28016.
Here are the steps to perform:
Create a network: docker network create my-net
Attach the network to the already running container: docker container attach <container-name> my-net
Start the new container with the --network my-net or with docker-compose add a network property:
...
networks:
- my-net
networks:
my-net:
external: true
The container should now be able to communicate using the container-name as a DNS host name
Related
I have a network 10.0.0.0/24 with 1 Oracle db-host01 ip address 10.0.0.100 and 2 docker hosts Docker01 10.0.0.15 and Docker02 10.0.0.16 and swarm is configured. I have configured a overlay network "overnet" with network address 192.168.6.0/24.
I have executed the below cmd to run a web container on overlay network.
docker run -i -t -d -p 9090:6000 --name portal --network overnet portal:1.0
but the web container is ip address 192.168.6.2 is not communicating with Oracale DB 10.0.0.100.
I can ping DB ip 10.0.0.100 from web container.
how I can make communication possible and can run this container as service as well.
regards
Sohail
Overlay networks are not attachable by default, which means that standalone containers cannot use them.
You can specify that a network should be attachable using the --attachable flag, such as
$ docker network create -d overlay --attachable overnet
If you are unable to modify the network, create a service for your container using
docker service create --network overnet --publish 9090:6000 --name portal portal:1.0
at which point it will be able to use the overlay network.
I am new to docker environment and trying to figure out how to make two container communicate with each other.
I have two running containers. Container 1 is having a inference engine running which performs inference on image it receives. Container 1 is listening on port 9001. Container 2 is having the image and wants to send it to Container 1, but is failing saying
port 9001 is already binded to some service
PS When I try to send the image from host to container 1, it works fine, but I cannot understand on how to achieve the same from another container. Any help would be really grateful. Thanks.
You can use docker-compose. It will create a bridge network for you when running the command docker-compose up, Each image defined in the Compose file will get launched in this network automatically.
If you are not using Docker-Compose and running individual container than expose both services port with the host.
docker run -p 9001:9001 image_1
docker run -p host's_port : container_port image_2
Then can to communicate using host IP
Like:
http://hostip : port
In my docker-compose , i have 2 containers .
How to make this 2 containers access each other as they installed in one host without containers .
How they can see each other and their file systems
To allow inter-container communication create a common bridge network, and put both containers into the same network. The build phase assuming nothing needs to "talk" to each other does not need the --network switch.
docker network create jointops
docker build --network jointops -t srv1 /srv1
docker build --network jointops -t srv2 /srv2
docker run --network jointops -d -t srv1
docker run --network jointops -d -t srv2
To check both machines are on the same network now issue the command
docker network inspect jointops
You should see both machines having an IP Allocation.
Ok... so how do they communicate ?
The bridge network - jointops by default will perform dns-resolution
So if srv1 has something like
curl -c http://srv2/bla/bla/bla
This will be resolved correctly.
Regarding Shared Data access ..
Do not run 2 apps in 1 container
Instead
create a docker volume
run 2 separate containers
each container can connect to the same volume
See here for inter-container communication. Each container encapsulates its contents, so use ports for communication instead of trying to just openly expose the full filesystem of one container to another.
If both applications need access to the same filesystem, consider running both in the same container. That is supported.
I have a container1 running a service1 on port1
also
I have a container2 running a service2 on port2
How can I access service2:port2 from service1:port1?
I mention that the container are linked together.
I ask if there is a way to do it without accessing the docker0 IP (where the port is visible)
thanks
The preferred solution is to place both containers on the same network, use the build-in dns discovery to reach the other node by name, and you'll be able to access them by the container port, not the host published port. By CLI, that looks like:
docker network create testnet
docker run -d --net testnet --name web nginx
docker run -it --rm --net testnet busybox wget -qO - http://web
The busybox shows a sample client container connecting to the nginx container with the name web, over port 80. Note that this port didn't need to be published to be reachable by other containers.
Setting up multi-container environments with their own network is a common task for docker-compose, so I'd recommend looking into this tool if you find yourself doing this a lot.
I run a docker swarm with docker swarm mode. Let's say I have 4 nodes, 1 manager, 3 worker. The hostnames are:
manager0
worker0
worker1
worker2
I start the service in global mode, so every node runs the service once.
Let's say the command looks like this:
docker service create --name myservice --mode global --network mynetwork ubuntu wait 3600
mynetwork is an overlay network.
Now I am trying to access the hostname of the docker host in the containers, so I can pass the hostname to an application in the container.
I tried to pass the hostname with the environment variables (--env hostname=$(hostname)), but actually ${hostname} is only executed on the manager and the hostname is set to manager0 for all nodes.
Is there a way to access the hostname or pass the hostname to the containers?
You can use latest naming templates to create service with hostname.
Here is the feature request, that has been implemented in docker version 17.10
https://github.com/moby/moby/issues/30966