How to link docker host to container by name - docker

I know how to link two containers, but can I link the host to a container in a similar way?
I have an nginx server on the host, I want it to connect to a container named my-varnish, which is linked to my-apachephp linked to my-mysql.
Currently I either map a port -p 8080:80 or find the bridge IP address (which is different each time I destroy and build a new set of containers). I would like to use the bridge IP by hostname without adding a dyn-dns registration process to each container.
Thoughts?!

Use the Docker run's add host functionality.It adds the host mapping in the container's host file.
From Usage :
--add-host value Add a custom host-to-IP mapping (host:ip) (default [])

Related

How docker process communication between different containers on default bridge on the same host?

Here is my situation:
First,I run a MySQL container(IP:172.17.0.2) on centOS;
Then I run a Nacos contanier with specified datasource(MySQL above) on the same host, but i didn't use the ip of the MySQL container, instead I used the ip of the bridge Gateway(172.17.0.1)(two containers both link to the default bridge).
What surprised me was that Nacos works well, it can query config data from MySQL container normally.
How did this happen? I have read some documention but didn't get the answer.It really confused me.
On modern Docker installations, try to avoid using the default bridge network. docker network create a network (it doesn't need any special options, but it does need to be created) and then launch your containers on --net that network. If you're using Compose, it creates a ("user bridge") network named default for you.
On your CentOS host, if you run ifconfig, you should see a docker0 interface with the 172.17.0.1 address. When you launch a container with the docker run -p option, that container is accessible via the first port number on all host interfaces, including the docker0 interface.
Meanwhile, inside a container (on the default bridge network), it sees that same IP address as the normal IPv4 gateway address (try docker run --rm busybox route -n). So, when you connect to 172.17.0.1:3306, you're connecting out to the host, and then connecting to the published port of the database container.
This isn't a totally standard way to connect between containers, though it will work. You should prefer using Docker named networks, which will let you connect to another container using the container's name without manually doing any IP-address lookups. If you really can't move off of the default bridge network, then the standard approach is to --link to the other container, but this entire path is considered outdated.

Can't resolve set hostname from another docker container in same network

I've had db and server container, both running in the same network. Can ping db host by its container id with no problem.
When I set a hostname for db container manually (-h myname), it had an effect ($ hostname returns set host), but I can't ping that hostname from another container in the same network. Container id still pingable.
Although it works with no problem in docker compose.
What am I missing?
Hostname is not used by docker's built in DNS service. It's a counterintuitive exception, but since hostnames can change outside of docker's control, it makes some sense. Docker's DNS will resolve:
the container id
container name
any network aliases you define for the container on that network
The easiest of these options is the last one which is automatically configured when running containers with a compose file. The service name itself is a network alias. This lets you scale and perform rolling updates without reconfiguring other containers.
You need to be on a user created network, not something like the default bridge which has DNS disabled. This is done by default when running containers with a compose file.
Avoid using links since they are deprecated. And I'd only recommend adding host entries for external static hosts that are not in any DNS, for container to container, or access to other hosts outside of docker, DNS is preferred.
I've found out, that problem can be solved without network using --add-host option. Container's IP can be gain using inspect command.
But when containers in the same network, they are able to access each other via it names.
As stated in the docker docs, if you start containers on the default bridge network, adding -h myname will add this information to
/etc/hosts
/etc/resolv.conf
and the bash prompt
of the container just started.
However, this will not have any effect to other independent containers. (You could use --link to add this information to /etc/hosts of other containers. However, --link is deprecated.)
On the other hand, when you create a user-defined bridge network, docker provides an embedded DNS server to make name lookups between containers on that network possible, see Embedded DNS server in user-defined networks. Name resolution takes the container names defined with --name. (You
will not find another container by using its --hostname value.)
The reason, why it works with docker-compose is, that docker-compose creates a custom network for you and automatically names the containers.
The situation seems to be a bit different, when you don't specify a name for the container yourself. The run reference says
If you do not assign a container name with the --name option, then the daemon generates a random string name for you. [...] If you specify a name, you can use it when referencing the container within a Docker network.
In agreement with your findings, this should be read as: If you don't specify a custom --name, you cannot use the auto-generated name to look up other containers on the same network.

Docker For Mac IP address

I am running an Elasticsearch in a Docker container. To access this from an app running inside another container I can specify elasticsearch host as the machine local IP address on a Mac.
I want to bundle the es host config inside the image, to make it just work without external files, but the issue I have is the image will only work with that IP, so a different mac on the network will not be able to use the image as the es host config will not be correct.
Any ideas how I can use a single IP in the config that will work in all cases, regardless if IP changes?
Linking both containers solved the issue (thanks for suggestion héctor)
By creating a custom network and adding both containers to the network, this allows them to communicate.
I then set Elasticsearch host to container name (of es container), as Docker will automatically resolve the container name to its internal IP.
Created network e.g. docker network create mynet
used --network mynet when running both containers & specified --name
Specified elasticsearch host using container name e.g. es-container

Is there a way to add a hostname to an EXISTING docker container?

I have some containers that communicate via their IP from the network docker.
I can use the option -h or --hostname when running a new container but I want to set the hostname for existing container.
Is it possible?
One way is to create network and add different container in this network.
When adding container in the network, you can use the --alias option of docker network. Like this:
Create a network:
docker network create <my-network-name>
Add containers in the network:
docker network connect --alias <hostname-container-1> <my-network-name> <container-1>
docker network connect --alias <hostname-container-2> <my-network-name> <container-2>
docker network connect --alias <hostname-container-3> <my-network-name> <container-3>
Enjoy.
So each container can see other container by the alias (the alias is used as hostname).
Generally, you would need to stop/restart a container, in order to run it again with -h (--hostname) (unless you used --net=host)
If you cannot stop the container, you can try and (in an attached bash session) edit its /etc/hostname.
The hostname is immutable once the container is created (although technically you can modify /etc/hostname).
As suggested in another answer, you cannot change the hostname by stopping or restarting the container. There are not Docker engine client parameters for the start command that affect hostname. That wouldn't make sense anyway as starting a container simply launches the ENTRYPOINT process in a container filesystem that has already been created (i.e. /etc/hostname has already been written).
It is possible to synchronize the container hostname with the host by using the --uts=host parameter when the container is created. This shares the UTS namespace. I would not recommend --net=host unless you also want to share the host network devices (i.e. bypass the Docker bridge).

questions about docker --link parameter

As we know, in one host with docker daemon, containers connect to the docker0 bridge, and so containers can access each other by default.
Then what's the use of --link option? Is it any different with the direct access by ip way?
What does it actually do?
From the Docker docs:
When you set up a link, you create a conduit between a source container and a recipient container. The recipient can then access select data about the source
When two containers are linked, Docker will set some environment variables in the target container to enable programmatic discovery of information related to the source container.
And some more:
In addition to the environment variables, Docker adds a host entry for the source container to the /etc/hosts file. Here's an entry for the web container:
So, basically --link creates a set of environment variables and adds some entries to the /etc/hosts file in order to ease communication. But, the containers are still directly accessed via IP.
When you create a container using --link option, Docker exposes the linked container into the new one in two ways:
It creates a entry in /etc/hosts with the IP of the linked container and the alias given when creating the link.
It exposes some information as environmental variables about the linked container. As Docker documentation shows:
Docker will then also define a set of environment variables for each port that is exposed by the source container. The pattern followed is:
<name>_PORT_<port>_<protocol> will contain a URL reference to the port. Where <name> is the alias name specified in the --link parameter (e.g. webdb), <port> is the port number being exposed, and <protocol> is either TCP or UDP. The format of the URL will be: <protocol>://<container_ip_address>:<port> (e.g. tcp://172.17.0.82:8080). This URL will then be split into the following 3 environment variables for convenience:
<name>_PORT_<port>_<protocol>_ADDR will contain just the IP address from the URL (e.g. WEBDB_PORT_8080_TCP_ADDR=172.17.0.82).
<name>_PORT_<port>_<protocol>_PORT will contain just the port number from the URL (e.g. WEBDB_PORT_8080_TCP_PORT=8080).
<name>_PORT_<port>_<protocol>_PROTO will contain just the protocol from the URL (e.g. WEBDB_PORT_8080_TCP_PROTO=tcp).
It is not differences if you access via IP, but using links let setting the container ignoring the ip that will be assigned by Docker Daemon. Check Docker documentation for further information.
If you start the docker using --icc=false option, the container can't communicate to each other by default. You must use --link to connect two containers.

Resources