I plan to split my monolthic server up into many small docker containers but haven't found a good solution for "inter-container communication" yet. This is my target scenario:
I know how to link containers together and how to expose ports, but none of these solutions are satisfying to me.
Is there any solution to communicate via hostnames (container names) between the containers like in a traditional server network?
That should be what
--link
is for, at least for the hostname part.With docker 1.10, and PR 19242, that would be:
(see last section below)
That is what Updating the
/etc/hosts
file detailsFor instance, launch an LDAP server:
And define an image to test that LDAP server:
You can expose the '
openldap
' container as 'internalopenldap
' within the test image with --link:Then, if you type 'lds', that alias will work:
That would return people. Meaning
internalopenldap
is correctly reached from theldaptest
image.Of course, docker 1.7 will add
libnetwork
, which provides a native Go implementation for connecting containers. See the blog post.It introduced a more complete architecture, with the Container Network Model (CNM)
That will Update the Docker CLI with new “network” commands, and document how the “
-net
” flag is used to assign containers to networks.docker 1.10 has a new section Network-scoped alias, now officially documented in
network connect
:Edit: After Docker 1.9, the
docker network
command (see below https://stackoverflow.com/a/35184695/977939) is the recommended way to achieve this.My solution is to set up a dnsmasq on the host to have DNS record automatically updated: "A" records have the names of containers and point to the IP addresses of the containers automatically (every 10 sec). The automatic updating script is pasted here:
Make sure your dnsmasq service is available on
docker0
. Then, start your container with--dns HOST_ADDRESS
to use this mini dns service.Reference: http://docs.blowb.org/setup-host/dnsmasq.html
As far as I know, by using only Docker this is not possible. You need some DNS to map container ip:s to hostnames.
If you want out of the box solution. One solution is to use for example Kontena. It comes with network overlay technology from Weave and this technology is used to create virtual private LAN networks for each service and every service can be reached by
service_name.kontena.local-address
.Here is simple example of Wordpress application's YAML file where Wordpress service connects to MySQL server with wordpress-mysql.kontena.local address:
The new networking feature allows you to connect to containers by their name, so if you create a new network, any container connected to that network can reach other containers by their name. Example:
1) Create new network
2) Connect containers to network
or
3) Ping container by name
See this section of the documentation;
Note: Unlike legacy
links
the new networking will not create environment variables, nor share environment variables with other containers.This feature currently doesn't support aliases
I just found the Tumtum Blog and stumbled upon this paragraph in the official Docker documentation. I don't know whether I had missed this paragraph all the time or whether it was newly added but that should be exactly what I need :)
EDIT : It is not bleeding edge anymore : http://blog.docker.com/2016/02/docker-1-10/
Original Answer
I battled with it the whole night. If you're not afraid of bleeding edge, the latest version of Docker engine and Docker compose both implement libnetwork.
With the right config file (that need to be put in version 2), you will create services that will all see each other. And, bonus, you can scale them with docker-compose as well (you can scale any service you want that doesn't bind port on the host)
Here is an example file
And the reference for this new version of compose file: https://github.com/docker/compose/blob/1.6.0-rc1/docs/networking.md