You create say 3 instances of that image (i.e. 3 containers) with different port mappings 5001:80, 5002:80, 5003:80. These are just specified at the command line (docker run -p5001:80)
Against the same containers you might also do 6001:22, 6002:22, 6003:22 to expose SSHD to different ports on the host.
This allows you to defer the decision of which containers will be listening where to deployment or runtime, giving you lots of flexibility.
OK, how does a client outside of my docker host know to connect to 5001 to get to container1 port 80 and 6001 to get to container1 port 22?
BTW, this was the scenario I mentioned initially as "I could go ham on it and move ports around."
Thanks again for the reply, getting somewhere.
So instead of your apps having hard coded endpoints, they go to some config file, zookeper, etcd to find the services. Your config management piece can register endpoints with the same directories as they come online.
An alternative is just to register with a load balancer dynamically.
This bit does take work but it gives your system a very nice dynamic fungible property.
Happy to discuss more offline with anyone as I'm a massive advocate of docker now! Same username at Twitter.
Docker will soon offer a better solution to service discovery. It will allow taking advantage of the various SD tools out there (zookeeper, etcd, synapse/haproxy, skynet, serf) while keeping your containers compatible with all of them. This will help keep all docker containers compatible with each other, instead of fragmenting them among mutually incompatible service discovery protocols.
Happy to chat about it more on irc - #docker and #docker-dev on Freenode.
To expand on this, a common pattern is to have a local proxy installed on each host machine. To route traffic to a new container, one simply updates the config for the local nginx/haproxy/hipache/other proxy.
A second layer of load balancing exposes the singular, top-level endpoint. All Docker hosts are registered with this LB, but those without live containers for a given service are simply "out of rotation" for that endpoint (health check failure).
This simplifies the service discovery aspect for architectures not already using a more sophisticated mechanism.
"In deployment, a routing layer handles routing requests from a public-facing hostname to the port-bound web processes."