Do you spot the mistake here?

docker run -p 5432:5432 --name postgres -d postgres

The reason I’m exposing port 5432 is so that I can run psql on the Docker host. But, but but. I’m running this on digitalocean so this exposes port 5432 to the internet at large!

The command above is the equivalent of:

docker run -p 0.0.0.0:5432:5432 --name postgres -d postgres

What I intended was:

docker run -p 127.0.0.1:5432:5432 --name postgres -d postgres

That binds to the local loopback address which is what I wanted.

As a side note if you have a docker image with psql that’s linked to the postgres container then simply using docker exec is the way to go. E.g.:

docker run --name postgres -d postgres
docker exec -t -i some-image-with-psql --link postgres:pg psql any-arguments-you-want-to-pass-to-sql

Link establishes environment variables (as the host ip address varies). In this case PG_PORT_5432_TCP_ADDR, PG_PORT_5432_TCP_PORT.