I’d highly recommend starting with the default Docker networking and understanding it. Containers don’t have accessible IP addresses; instead, they use the host’s IP address, and the docker run -p option causes specific ports to appear on your host.
You can think of a container as a process (what’s the IP address of your nginx process vs. your elasticsearch process?), or you can think of your host system as a router (can I give a system behind the router an IP address visible from the outside? you can but only with special setup on the router).
So here’s a basic setup for Elasticsearch. It’s going to be a little bit more qualitative than a full-on recipe. You need to know some contact information, say an IP address or a hostname, for both host systems. On each system, modify the Elasticsearch configuration (using docker run -v to push in a config file is handy here) to say:
network.publish_host: (this host's IP address)
discovery.zen.ping.multicast.enabled: false
discovery.zen.ping.unicast.hosts:
- (this host's IP address)
- (other host's IP address)
Then run Elasticsearch containers on both hosts with docker run -p 9200:9200 -p 9300:9300, and they will find each other.
[N.B. the setup I have readily available is for Elasticsearch 1.7, IIRC Elasticsearch 2.x disables zen multicast discovery by default and there may be other differences]