How Docker Container can access each other - docker

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.

Related

Cannot connect interface to Docker container

I am trying to connect and run a device (LiDAR) through Docker container since it needs Ubuntu 16 while my computer is Ubunutu 20.
I got the device to ping inside the docker container, but it is not recognised when I try to use it.
What I did:
Made Dockerfile with requirements (Added EXPOSE to expose all ports)
Built docker image using:
docker build -t testLidar
I then made a container using
docker run -d -P --name test_Lidar (imagename)
Then
docker exec -t test_Lidar (device_ip) works
I am able to ping my LiDAR IP inside the container, but when I do ip a I cannot see the interfaces connected to my machine.
Been stuck on this for 3 days, any suggestions?
Note: I have done the exact same steps but on an Ubuntu 16 machine. The only change was the docker run command had --net host instead of -P tag and my device worked perfectly. I feel like this is the root of my problem.
Use --net host flag with docker run to attach the container to your host's networking stack and make it available in for other hosts in your network.
When you use --net host, you actually attach the container to your host's networking stack. By default, containers are attached to the default network of type bridge and can communicate with each other. You can then reach them only from your host using its ip addresses typically in subnet 172.17.0.0/16.
Using -P actually binds exposed ports from a container with randomly selected free ports on your host. It should be used for exposing network services (eg. web server with port 80), but not for ICMP ping.

Docker network bridge

I'm trying to run multiple containers with the same ports on docker.
For this, I have created a network in brigde mode and specified a subnet.
docker network create -d --subnet 192.168.99.0/24 mynetwork
Then connected the docker containers to it with a static IP.
docker run -i -t -d -p 2377:2377 -p 7946:7946 -p 4789:4789-name container image
docker network connect --ip 192.168.99.98 mynetwork container
I did this with three containers (using different IP's), after starting the second one I got:
Error response from daemon: driver failed programming external connectivity on endpoint container(...): Bind for 0.0.0.0:7946 failed: port is already allocated
As far as I'm concerned, I should not be getting this error, due to bridge mode.
The docker run -p option allocates a port on the host system; those are shared across all containers, independently of what Docker-private network they’re using. These also will conflict with non-Docker processes running on the host.
If your goal is just to be able to communicate between containers on the same network, you don’t need a -p option at all. They can use each others’ --name and the port the service inside the container is listening on to connect.
If you’re trying to run multiple Docker container stacks at the same time, you need to decide which specific instance port 2377 on your host will route to, and change the other container’ -p option.
Specifically setting the Docker-internal private IP addresses (or worrying about them at all) is almost never necessary. I’d delete those --subnet and --ip options. To communicate between containers, put them on the same network as described above; from outside you need a (unique) -p option.

dockerized app needs to interact with other dockers over localhost

I have an app that launches a docker container and automates a few of the routines.
Now I have dockerized this app which is not able to talk to other containers over localhost. I tried setting
--network host
when launching the container and now not able to access the containerized webapp over localhost:.
Any pointers?
localhost won't work. Suppose, you are running a VM and try to talk to your host/ other VMs running in your machine. If you call localhost from one of the VMs, it's localhost for that VM only, not to your host. So, you won't be able to talk from one VM to another by calling localhost. Docker works same in regard to the localhost. You have two options,
Use a network
If you are using network, create a network and add all the containers to that network. This is the new suggested way by docker.
docker network create <your-network-name>
docker run --network <your-network-name> --name <container-name1> <image>
docker run --network <your-network-name> --name <container-name2> <image>
Then use the container name (container-name1) to talk to that service from other service (container-name2).
Use --link option
Or you could use --link option, which is a legacy system for docker. Docker docs says, unless you have a specific reason to use, don't use --link anymore.
docker run --name <container1> <image>
docker run --name <container2> <image>
You could use container1 to talk from container2 and vice versa. You could use these container name in places like DB host, etc.
did you try creating a common bridge network and attach your containers to the same network:
create network :-
docker network create networkname
and then in docker run command add this switch --network=networkname
I figured it later after going over a lot of other documents.
Step 1: install docker inside the container. Added following line to my dockerfile
RUN curl -sSL https://get.docker.com/ | sh
Step 2: provide volume-mapping in docker run command
-v /var/run/docker.sock:/var/run/docker.sock
Now hosts' docker commands are accessible from within my current container and without changing the --network for current docker container, I'm able to access other containers over localhost

How to set docker back to default configuration

I have installed docker compose and used it a little. Then decided I did not need it it. Now when I create containers by hand they are assigned a network with an ip address, gateway and other things. When I inspected older containers before i installed docker compose they do not have these network settings.
I have tried unoinstalling docker compose and reinstalling docker which did not work. Is there anything I can do? The reason I am asking is I can't link containers together because every new container is assigned an ip address and other network settings.
Docker always does that, nothing to do with compose. Compose doesn't modify your Docker installation in any way, purely connects to the daemon to run commands under the hood.
By linking containers together I'm assuming you mean just so they can communicate with each other? --link is deprecated for some time now in favor of docker network .... Try the following:
$ docker network create test-net
$ docker run -d --name c1 --net test-net alpine:3.3 sleep 20000
$ docker run -it --name c2 --net test-net alpine:3.3 ping c1

how to bind specific interface in docker container?

I have a program which has two mandatory arguments -d and -t, both of them mean that bind to a specific network device (IP address), i.e.: ./myprogram -d 172.17.0.2 -t 172.17.0.3, and they can't be the same.
Now, I need to run this program in a docker container, how could I config the container so that I can run this program inside the container and for peer endpoint it is the same as I run this program in the host?
Thanks!
if your container needs to access your network device, you need to share the network devices
docker run --net-host...
extract from
docs.docker.com/engine/reference/run/#ipc-settings---ipc
Network: host With the network set to host a container will share the host’s network stack and all interfaces from the host will be available to the container.
an example, extract from this image using nethogs for network monitoring
https://hub.docker.com/r/k3ck3c/nethogs/
docker run -it --net=host -- --rm k3ck3c/nethogs

Resources