If you want to get Postgres on macOS working, you can easily use brew install postgres
.
But this way also has its drawbacks. Managing multiple versions or doing major version upgrades becomes a pain.
There's an easier way to set up PostgreSQL on Mac and to manage multiple versions: installing Postgres with Docker.
In this article, we'll set up Postgres 12 and 13 on macOS Big Sur with Docker.
TL;DR:
# create folder for docker volume
mkdir -p $HOME/docker/volumes/postgres-13
# create and start postgres 13 docker container
docker run --rm --name postgres-13 -p 127.0.0.1:5013:5432 -v $HOME/docker/volumes/postgres-13:/var/lib/postgresql/data -e POSTGRES_PASSWORD=postgres -d postgres:13-alpine
# connect
psql -h localhost -p 5013 -U postgres
# stop
docker stop postgres-13
Before we get to Postgres, we need two things installed before we start.
First, we need to install Docker on macOS. Follow the instructions on docker.com to install the official Docker for Mac.
Also, start the Docker application and go through their Getting Started guide to make sure everything works.
You may need to restart your shell for the docker
cli command to work.
If you haven't already, install the Brew package manager.
Then, update Brew and install libpq:
brew update
brew install libpq
As a last step, symlink psql
and the other libpq tools to your local binaries (/usr/local/bin
):
brew link --force libpq
Now we can install Postgres 13.
We'll start by creating a folder for our persistent Docker volume:
mkdir -p $HOME/docker/volumes/postgres-13
Next, we'll create and start a Docker container with Postgres 13:
docker run --rm --name postgres-13 -p 127.0.0.1:5013:5432 -v $HOME/docker/volumes/postgres-13:/var/lib/postgresql/data -e POSTGRES_PASSWORD=postgres -d postgres:13-alpine
Let's unpack this command:
docker run
is the command to start a container (and download it if it isn't cached locally)--rm
makes Docker delete this container when it is stopped--name postgres-13
gives the container its name-p 127.0.0.1:5013:5432
exposes port 5432
(Postgres standard port) from the container to our local interface (127.0.0.1
) on port 5013-v $HOME/docker/volumes/postgres-13:/var/lib/postgresql/data
mounts the data directory we created earlier into the correct place inside the Postgres Docker container-e POSTGRES_PASSWORD=postgres
sets the connection password for the postgres
user to postgres
-d
makes the container run in detached mode (in the background)postgres:13-alpine
describes the Docker image we want to useI like port 5013 because this makes it easy to distinguish different Postgres versions. 5013 for PG 13, 5012 for PG 12 and so on.
And because we exposed to the local 127.0.0.1
interface only, nobody can connect to this Postgres instance from outside our own Mac.
We can now connect to the container with the following psql
command:
psql -h localhost -p 5013 -U postgres
Just type in the password postgres
when required.
The connection string for this Postgres instance is postgres://postgres:postgres@127.0.0.1:5013
.
Don't worry If you get an error like the following, that means Postgres is setting itself up for the first time. This may take a minute or two:
ā ~ psql -h localhost -p 5012 -U postgres
psql: error: server closed the connection unexpectedly
This probably means the server terminated abnormally
before or while processing the request.
This works fabulously with other postgres versions, too! Just replace every 13 with a 12:
mkdir -p $HOME/docker/volumes/postgres-12
docker run --rm --name postgres-12 -p 127.0.0.1:5012:5432 -v $HOME/docker/volumes/postgres-12:/var/lib/postgresql/data -e POSTGRES_PASSWORD=postgres -d postgres:12-alpine
psql -h localhost -p 5012 -U postgres
docker stop postgres-12