While working on RubyBench, I was trying to execute the following Docker commands through Net::SSH in Ruby:

docker run --name discourse_redis -d redis:latest &&
docker run --name discourse_postgres -d postgres:latest &&
docker run --rm --link discourse_postgres:postgres --link discourse_redis:redis -e \"RAILS_COMMIT_HASH=#{commit_hash}\"  tgxworld/discourse_rails_head_bench"
# Dockerfile

FROM tgxworld/ruby:0.1
MAINTAINER Guo Xiang "tgx_world@hotmail.com"

# ...

CMD /bin/bash -l -c "./runner && cd discourse && ruby script/bench.rb -m -n"
# !/bin/bash
set -e

cd /
createdb -T template0 -h "$POSTGRES_PORT_5432_TCP_ADDR" -p "$POSTGRES_PORT_5432_TCP_PORT" -U postgres discourse_profile
pg_restore --no-owner -h "$POSTGRES_PORT_5432_TCP_ADDR" -p "$POSTGRES_PORT_5432_TCP_PORT" -U postgres -d discourse_profile 

This resulted in the following error when trying to create a new DB in PostgreSQL:

createdb: could not connect to database template1: could not connect to server: Connection refused
    Is the server running on host "172.17.2.206" and accepting
    TCP/IP connections on port 5432?

So the question I asked was "Why isn't the connection available even though I've already linked the containers?" To make matters worst, I couldn't replicate the error when running the commands manually. After Googling for what seems like hours to me, I finally found the issue "Is there a way to delay container startup to support dependant services with a longer startup time" which explained why the connection to PostgreSQL was failing. Running Docker commands through Net::SSH, instead of manually by hand, executed the script which creates the database even before the PostgreSQL server has been established in the detached PostgreSQL container. In order to ensure that the script only runs after the PostgreSQL connection has been established, we can ping the port and only executes the script once the connection has been established.

# !/bin/bash
set -e

# See https://github.com/dominionenterprises/tol-api-php/blob/master/tests/provisioning/set-env.sh
while ! exec 6<>/dev/tcp/${POSTGRES_PORT_5432_TCP_ADDR}/${POSTGRES_PORT_5432_TCP_PORT}; do
  echo "$(date) - still trying to connect to Postgres server"
  sleep 1
done

cd /
createdb -T template0 -h "$POSTGRES_PORT_5432_TCP_ADDR" -p "$POSTGRES_PORT_5432_TCP_PORT" -U postgres discourse_profile
pg_restore --no-owner -h "$POSTGRES_PORT_5432_TCP_ADDR" -p "$POSTGRES_PORT_5432_TCP_PORT" -U postgres -d discourse_profile 

Hopefully this helps!