Getting around Docker’s host network limitation on Mac
I usually use linux for my dev work. With the recent WFH situation, however, I didn’t have access to my remote linux machine temporarily and had to do some work locally on my mac.
On linux, I usually spin-off a local instance of a postgres database using docker on the host network then use a psql client running natively on the host to connect to the database. According to the docker documentation:
If you use the
host
network mode for a container, that container’s network stack is not isolated from the Docker host (the container shares the host’s networking namespace), and the container does not get its own IP-address allocated. For instance, if you run a container which binds to port 80 and you usehost
networking, the container’s application is available on port 80 on the host’s IP address.
On mac, however, unlike the behavior on linux, my local psql terminal was failing to find any postgres server running on host port 5432 even though I launched the docker container with the ( — network host) option.
It turns out Docker’s host networking feature is not supported on Mac — even though the docker run command doesn’t complain about it.
The reason for that behavior is that on mac, docker daemon is actually running in a virtual machine, not natively on the host. Thus, it’s not connecting to host ports for your Mac, but rather it’s connecting to host ports of the virtual machine.
EXAMPLE
To go through that scenario mentioned above and how to get around it, here’s a step-by-step guide:
Let’s say I started a postgres docker container and would like to connect to it via psql, the interactive terminal for working with Postgres databases running as a process on my mac host.
### Run the postgres container in the detached mode
[~]$ docker run --rm --name some-postgres --network host -e POSTGRES_PASSWORD=mypassword -d postgres#### Validate the docker container is sunning
[~]$ docker ps --format "table {{.ID}} {{.Names}} {{.Ports}}"CONTAINER ID NAMES PORTS079ca5a9cdd6 some-postgres
#### Run psql[~]$ psql -U postgres -h localhostpsql: error: could not connect to server: could not connect to server: Connection refusedIs the server running on host "localhost" (127.0.0.1) and acceptingTCP/IP connections on port 5432?could not connect to server: Connection refusedIs the server running on host "localhost" (::1) and acceptingTCP/IP connections on port 5432?
As you can see, psql fails to find a postgres server at host port 5432.
WORKAROUND
One way around it is port forwarding to localhost. -P, — publish also work.
You can either port forward a specific port (-p 5432:5432) or all ports a container uses (-P).
Exposing a specific port:
[~]$ docker run — rm — name some-postgres -p 5432:5432 -e POSTGRES_PASSWORD=mypassword -d postgres# Successfully connected [~]$ psql -U postgres -h localhost
Password for user postgres:
psql (12.1)
Type "help" for help.
postgres=#
Or all ports:
[~]$ docker run — rm — name some-postgres -P -e POSTGRES_PASSWORD=mypassword -d postgres# Get the host port to which port 5432 is mapped to
[~]$ port=$(docker port some-postgres 5432 | sed “s/.*://g”)# Use the host port to successfully connect to postgres
[~]$ psql -U postgres -h localhost -p $port
Password for user postgres:
psql (12.1)
Type "help" for help.
postgres=#