Search code examples
postgresqlazuredockerpactpact-broker

How to connect the Pact Broker to a local or cloud instance of PostgreSQL?


I'm struggling to get the Pact Broker running in a docker container to connect to my local installation of PostgreSQL on Windows.

This is what my docker run command looks like...

docker run pactfoundation/pact-broker 
-e PACT_BROKER_DATABASE_USERNAME=pact_broker 
-e PACT_BROKER_DATABASE_PASSWORD={Password} 
-e PACT_BROKER_DATABASE_HOST=host.docker.internal 
-e PACT_BROKER_DATABASE_NAME=pact_broker 
-e PACT_BROKER_DATABASE_PORT=5432 
-p 9292:9292

Which returns the following error...

Unable to load application: Sequel::DatabaseConnectionError: PG::ConnectionBad: could not connect to server: No such file or directory
        Is the server running locally and accepting
        connections on Unix domain socket "/tmp/.s.PGSQL.5432"?
bundler: failed to load command: puma (/pact_broker/vendor/bundle/ruby/2.6.0/bin/puma)
Sequel::DatabaseConnectionError: PG::ConnectionBad: could not connect to server: No such file or directory
        Is the server running locally and accepting
        connections on Unix domain socket "/tmp/.s.PGSQL.5432"?

Here is my database and user in pgAdmin 4

enter image description here

Here is the command I'm using to test my connection

psql postgresql://pact_broker:{Password}@localhost/pact_broker

Which returns the following...

psql (13.3)
WARNING: Console code page (65001) differs from Windows code page (1252)
         8-bit characters might not work correctly. See psql reference
         page "Notes for Windows users" for details.
Type "help" for help.

pact_broker=>

I've also tried running the following command which returns the same error

docker run pactfoundation/pact-broker -e PACT_BROKER_DATABASE_URL=postgresql://pact_broker:{Password}@host.docker.internal/pact_broker -p 9292:9292

My postgres.conf file contains listen_addresses = '*' and my pg_hba.conf contains the following

# TYPE  DATABASE        USER            ADDRESS                 METHOD

# "local" is for Unix domain socket connections only
local   all             all                                     scram-sha-256
# IPv4 local connections:
host    all             all             127.0.0.1/32            scram-sha-256
# IPv6 local connections:
host    all             all             ::1/128                 scram-sha-256
# Allow replication connections from localhost, by a user with the
# replication privilege.
local   replication     all                                     scram-sha-256
host    all             all             0.0.0.0/0               trust
host    replication     all             ::1/128                 scram-sha-256
host    all             all             ::/0                    md5

I'm having similar problems with an instance hosted with Azure Database for PostgreSQL

My connection string looks like the following...

psql "host=pactbrokerserver.postgres.database.azure.com port=5432 dbname={your_database} user=postgres@pactbrokerserver password={your_password} sslmode=require"

Which I've attempted to connect to via the pact broker locally with...

docker run pactfoundation/pact-broker 
-e PACT_BROKER_DATABASE_USERNAME=postgres@pactbrokerserver 
-e PACT_BROKER_DATABASE_PASSWORD={Password} 
-e PACT_BROKER_DATABASE_HOST=pactbrokerserver.postgres.database.azure.com 
-e PACT_BROKER_DATABASE_NAME=pactbroker 
-e PACT_BROKER_DATABASE_PORT=5432 
-e PACT_BROKER_DATABASE_CONNECT_MAX_RETRIES=5 
-p 9292:9292

And it returns exactly the same error.

What could be the issues here?

enter image description here


Solution

  • I think what's happening here is that you've put the container name before the environment argument list to the docker run command.

    So instead of setting the PACT_BROKER_DATABASE_NAME and other environment variables for the running container with your custom values, they are simply being discarded by the runtime.

    Try this instead:

    docker run -e PACT_BROKER_DATABASE_USERNAME=pact_broker \
    -e PACT_BROKER_DATABASE_PASSWORD={Password} \
    -e PACT_BROKER_DATABASE_HOST=host.docker.internal \
    -e PACT_BROKER_DATABASE_NAME=pact_broker \
    -e PACT_BROKER_DATABASE_PORT=5432 \
    -p 9292:9292 \
    pactfoundation/pact-broker 
    

    Debugging Options

    In case I'm wrong, it seems likely that the issue could be network path related. To rule this out, we can get a shell into the docker container by replacing the entrypoint (which is usually the script to start and run the web server) with /bin/sh:

    docker run -it --entrypoint /bin/sh --user root -e PACT_BROKER_DATABASE_USERNAME=pact_broker -e PACT_BROKER_DATABASE_PASSWORD=Penwater858 -e PACT_BROKER_DATABASE_HOST=host.docker.internal -e PACT_BROKER_DATABASE_NAME=pact_broker -e PACT_BROKER_DATABASE_PORT=5432 -p 9292:9292 pactfoundation/pact-broker
    # once in the container...
    apk update
    apk add busybox-extras
    # see if there is a network path
    telnet $PACT_BROKER_DATABASE_HOST $PACT_BROKER_DATABASE_PORT