Update 2015/09/13

As of, at least, docker 1.8.1 when you start a container the /etc/hosts files inside other containers in the same environment get updated with a hostname making communication between containers much easier:

172.17.0.5  e2e-docker.bridge
172.17.0.5  e2e-docker
172.17.0.6  seleniumff
172.17.0.6  seleniumff.bridge

(Example is available on github).

Unless you want to install selenium in the same container as your app, which defeats the purpose of containers, you need some kind of bidirectional link - which is a problem as linking containers with --link creates a source to recipient unidirectional link.

You could look up containers IP addresses, but you would need to look these up at runtime every time.

Docker’s new network interface is a solution as you can see in option 1 here. Unfortunately at the time of this blog post, this feature is still experimental and not available in the latest stable docker.

So, for now, a hassle free way of doing this is using the --net flag with docker run to join the two containers’ network stacks.

--net container:<container name|id> will reuse another containers network stack.

See these slides on the --net flag for a diagram of what is happening slideshare.net/allingeek/single-host-docker-networking.

docker run --name seleniumff -d -p 3030:3030 -p 4444:4444 -p 5900:5900 selenium/standalone-firefox-debug

docker run -it --name e2e-docker --net=container:seleniumff -v ${PWD}/:/usr/src/ -w /usr/src/ iojs:2.4.0 /bin/bash	

In the code above all the ports that need to be published are done on the selenium container. 3030 that the app inside e2e-docker will be running on, 4444 the port selenium is running on on the official selenium images, and 5900 is used to access the container with a vnc client if you would like to watch the browser in action vnc://<boot2docker-ip>:5900 see the selenium debugging documentation.

vnc screenshot

You can then start running end-to-end tests that are located in the application codebase:

client
  .url('http://0.0.0.0:3030')
  .isVisible('.button-collapse').then(function(isVisible) {
    expect(isVisible).to.be.false;
  })
  .windowHandleSize({width: 800, height: 600})
  .isVisible('.button-collapse').then(function(isVisible) {
    expect(isVisible).to.be.true;
  })

An example is available on github.