DNS not working between two linked docker containers - getaddrinfo EAI_AGAIN error - docker

I am attempting to setup a temporary environment where I can execute ATs against a web application. To achieve this I have 3 docker containers:
Container 1: Database (mongo_local)
docker build -t mongo_local ./test/AT/mongo
docker run --name mongo_local -d -p 27017:27017 mongo_local
Container 2 (Web application):
docker run --name mywebapp_local -d -p 4431:4431 --link mongo_local -v /applicationdata:/applicationdata mywebapp
Container 3 (Newman test runner):
docker build -t newman_runner ./test/AT/newman
docker run --name newman_runner --link mywebapp_local newman_runner
The web application can access the database successfully using the following connection string: mongodb://mongo_local:27017/mydb, note that I am able to reference mongo_local, I dont have to specify an IP address for the mongo_local container.
The newman test runner runs postman tests against the web application and all tests execute successfully when I specify the IP address of the mywebapp_local container i.e. 10.0.0.4 in the URL, however if I specify the name mongo_local in the URL it does not work.
Hence https://mywebapp_local/api/v1/method1 does not work but https://10.0.0.4/api/v1/method1 does work.
The error Im getting is
getaddrinfo EAI_AGAIN mywebapp_local mywebapp_local:443 at request ...
I've tried using -add-host in the docker run command and this makes no difference. Is there anything obvious that I'm doing wrong?

As you have it set up, the newman_runner container doesn't --link mongo_local and that's why it can't see it.
Docker has been discouraging explicit inter-container links for a while. If you create a Docker-internal network and attach each container to it
docker network create testnet
docker run --net testnet ...
it will be able to see all of the other containers on the same network by their --name without an explicit --link.

Related

Why docker container is not able to access other container?

I have 3 docker applications(containers) in which one container is communicating with other 2 containers. If I run that containers using below command, container 3 is able to access the container 1 and container 2.
docker run -d --network="host" --env-file container1.txt -p 8001:8080 img1:latest
docker run -d --network="host" --env-file container2.txt -p 8080:8080 img2:latest
docker run -d --network="host" --env-file container3.txt -p 8000:8080 img3:latest
But this is working only with host network if I remove this --network="host" option then I am not able to access this application outside(on web browser). In order to access it outside i need to make the host port and container ports same as below.
docker run -d --env-file container1.txt -p 8001:8001 img1:latest
docker run -d --env-file container2.txt -p 8080:8080 img2:latest
docker run -d --env-file container3.txt -p 8000:8000 img3:latest
With this above commands i am able to access my application on web browser but container 3 is not able to communicate with container 1. here container 3 can access the container 2 because there i am exposing 8080 host + container port. But i can't expose again 8080 host port for container 3.
How to resolve this issue??
At last my goal is this application should be accessible on browser without using host network, it should use the bridge network . And container 3 needs to communicate with container 1 & 2.
On user-defined networks, containers can not only communicate by IP address but can also resolve a container name to an IP address. This capability is called automatic service discovery.
Read this for more details on Docker container networking.
You can perform the following steps to achieve the desired result.
Create a private bridge network.
docker network create --driver bridge privet-net
Now start your application containers along with the --network private-net added to your docker run command.
docker run -d --env-file container1.txt -p 8001:8001 --network private-net img1:latest
docker run -d --env-file container2.txt -p 8080:8080 --network private-net img2:latest
docker run -d --env-file container3.txt -p 8000:8000 --network private-net img3:latest
With this way, all the three containers will be able to communicate with each other and also to the internet.
In this case when you are using --network=host, then you are telling docker to not isolate the network rather to use the host's network. So all the containers are on the same network, hence can communicate with each other without any issues. However when you remove --newtork=host, then docker will isolate the network as well there by restricting container 3 to communicate with container 1.
You will need some sort of orchestration service like docker compose, docker swarm etc.

How to create websocket connection between two Docker containers

I've got two Docker containers that need to have a websocket connection between the two.
I run one container like this:
docker run --name comm -p 8080:8080 comm_module:latest
to expose port 8080 to the host. Then I try to run the second container like this:
docker run --name test -p 8080:8080 datalogger:latest
However, I get the error below:
docker: Error response from daemon: driver failed programming external
connectivity on endpoint test
(f06588ee059e2c4be981e3676d7e05b374b42a8491f9f45be27da55248189556):
Bind for 0.0.0.0:8080 failed: port is already allocated. ERRO[0000]
error waiting for container: context canceled
I'm not sure what to do. Should I connect these to a network? How do I run these containers?
you can't bind the same host port twice in the same time you may change one of the ports on one container:
docker run --name comm -p 8080:8080 comm_module:latest
docker run --name test -p 8081:8080 datalogger:latest
you may check the configuration in the containers on how they communicate .
you can also create link between them:
docker run --name test -p 8081:8080 --link comm datalogger:latest
I finally worked it out. These are the steps involved for a two-way websocket communication between two Docker containers:
Modify the source code in the containers to use the name of the other container as the destination host address + port number (e.g. comm:port_no inside test, and vice versa).
Expose the same port (8080) in the Dockerfiles of the two containers and build the images. No need to publish them as they are will be visible to other containers on the network.
Create a user-defined bridge network like this:
docker network create my-net
Create my first container and attach it to the network:
docker create --name comm --network my-net comm_module:latest
Create my second container and attach it to the network:
docker create --name test --network my-net datalogger:latest
Start both containers by issuing the docker start command.
And the two-way websocket communication works nicely!
My Solution works fine.
docker network create mynet
docker run -p 443:443 --net=mynet --ip=172.18.0.3 --hostname=frontend.foobar.com foobarfrontend
docker run -p 9999:9999 --net=mynet --ip=172.18.0.2 --hostname=backend.foobar.com foobarbackend
route /P add 172.18.0.0 MASK 255.255.0.0 10.0.75.2
the foobarfrontend calls a wss websocket on foobarbackend on port 9999
PS: i work on docker windows 10 with linuxcontainers
have fun

No such image or container error

I want to setup a rancher server and a rancher agent on the same server.
Here is what i have done for creating server:
docker run -d --restart=unless-stopped -p 8080:8080 rancher/server:stable
Then, I have opened my web-browser on 8080 port.
I have chosen a login/password and enabled access control.
Then i wanted to create a host (agent). Rancher web interface says me to type this command:
docker run -e CATTLE_AGENT_IP=x.x.x.x --rm --privileged -v /var/run/docker.sock:/var/run/docker.sock -v /var/lib/rancher:/var/lib/rancher rancher/agent:v1.2.10 http://nsxxx.ovh.net:8080/v1/scripts/yyyy:1514678400000:zzzz
I have no error message, but I do not see any entry in host section (in rancher web interface).
So I tried to execute a shell on the agent docker container:
docker exec -ti xxxxx /bin/bash
I tried to manually run run.sh script and here is what I see:
Error: No such image or container: nsxxx
I suppose this is because docker containers cannot communicate together, but I have done exactly what is in the documentation...
Thanks for your help
For docker exec your need to replace the xxxxx string with the container id or the name of the container. Both you get from the docker ps command

How do I create a Docker container with a hostname that an other container can use?

So I've created a container for RabbitMq with the following command.
docker run -d --hostname my-rabbit --name some-rabbit rabbitmq:3-management
Which works fine, but I then created another container with the following command
docker run test .
This runs a container with a PHP file that tries to connect to the hostname, my-rabbit but it can't find it the host so the PHP just closes itself right away. I did, however, find out the IP of the my-rabbit( first container ) and replace the hostname( my-rabbit ) in my PHP code with the IP and it connects with no problems.
So how do I create a hostname for the RabbitMq that all the other container on the same network can see and use instead of an IP?
I found out the answer after making this post. I use the --link arg with docker run.
https://docs.docker.com/engine/userguide/networking/default_network/dockerlinks/#communication-across-links

Docker in Docker: Port Mapping

I have found a similar thread, but failed to get it to work. So, the use case is
I start a container on my Linux host
docker run -i -t --privileged -p 8080:2375 mattgruter/doubledocker
When in that container, I want to start another one with GAE SDK devserver running.
At that, I need to access a running app from the host system browser.
When I start a container in the container as
docker run -i -t -p 2375:8080 image/name
I get an error saying that 2375 port is in use. I start the app, and can curl 0.0.0.0:8080 when inside both containers (when using another port 8080:8080 for example) but cannot preview the app from the host system, since lohalhost:8080 listens to 2375 port in the first container, and that port cannot be used when launching the second container.
I'm able to do that using the image jpetazzo/dind. The test I have done and worked (as an example):
From my host machine I run the container with docker installed:
docker run --privileged -t -i --rm -e LOG=file -p 18080:8080
jpetazzo/dind
Then inside the container I've pulled nginx image and run it with
docker run -d -p 8080:80 nginx
And from the host environment I can browse the nginx welcome page with http://localhost:18080
With the image you were using (mattgruter/doubledocker) I have some problem running it (something related to log attach).

Resources