in Tips

Pact Broker setup with docker-compose

Almost all projects that I work with are set up through docker-compose by myself. This pact broker set up was no exception. There are so many advantages using docker-compose, specially on local environment.

Pact broker itself requires additional post, so I am not going to talk about it at all in this post…

These are the versions of docker and docker-compose respectively:

 macmini @ ~/projects/pact_broker * master
 [30] ? docker version
Client:
 Version:           18.09.1
 API version:       1.39
 Go version:        go1.10.6
 Git commit:        4c52b90
 Built:             Wed Jan  9 19:35:23 2019
 OS/Arch:           linux/amd64
 Experimental:      false


Server: Docker Engine - Community
 Engine:
  Version:          18.09.1
  API version:      1.39 (minimum version 1.12)
  Go version:       go1.10.6
  Git commit:       4c52b90
  Built:            Wed Jan  9 19:02:44 2019
  OS/Arch:          linux/amd64
  Experimental:     false


macmini @ ~/projects/pact_broker * master
 [31] ? docker-compose version
docker-compose version 1.17.0, build ac53b73
docker-py version: 2.5.1
CPython version: 2.7.13
OpenSSL version: OpenSSL 1.0.1t  3 May 2016

my pact broker project’s directory structure

docker-compose.yml content

version: '3.2'
services:
postgresdb:
build:
context: ./db
dockerfile: ./db/Dockerfile
expose:
- "5432"
volumes:
- ./db/data:/var/lib/postgresql/data
environment:
- PACTBROKER_USER_PASSWORD
- POSTGRES_PASSWORD
- POSTGRES_USER=admin
- PGDATA=/var/lib/postgresql/data/pgdata
restart: 'always'
pactbroker:
image: dius/pact-broker
links:
- "postgresdb:postgresdb"
environment:
      - "PACT_BROKER_DATABASE_PASSWORD=${PACTBROKER_USER_PASSWORD}"
      - "PACT_BROKER_DATABASE_USERNAME=pactbrokeruser"
      - "PACT_BROKER_DATABASE_HOST=postgresdb"
      - "PACT_BROKER_DATABASE_NAME=pactbroker"
ports:
- "8081:80"
restart: 'always'

One thing to note here is that I’ve hardcoded database name, database host, and pact broker’s database username since it’s local environment for development purpose. In production like environment, probably all of information can be pulled from environment rather than hardcoding them.

So on local environment, only information that you should set are PACTBROKER_USER_PASSWORD and POSTGRES_PASSWORD before running docker-compose up or docker-compose up -d.

Dockerfile file content

  [53] ? cat Dockerfile 
## Base image
FROM postgres

## Of course, every Dockerfile requires a maintainer
MAINTAINER me

## Add a special script to initialize db for pact broker
ADD ./initial.sh /docker-entrypoint-initdb.d/

Dockerfile itself is pretty simple as shown above since only operation it has to do is to create a new database, new user, and grant the user full permission to the new database for pact broker and there is the entrypoint script that deals with that.

initial.sh file content

 #!/bin/bash
set -e

psql -v ON_ERROR_STOP=1 --username admin <<-EOSQL
  CREATE USER pactbrokeruser WITH PASSWORD '$PACTBROKER_USER_PASSWORD';
  CREATE DATABASE pactbroker WITH OWNER pactbrokeruser;
  GRANT ALL PRIVILEGES ON DATABASE pactbroker TO pactbrokeruser;
EOSQL

That is it! The above script will be executed once when a new container is created via docker-compose and it will create a new user, a new database, and grant the user all privileges to the database.

Start Up!

Once those are in place, get back to the root of the project file and execute this:

docker-compose up

Only reason why I am not executing it in background mode is to see if there is any issue starting up the broker. Once confirming log stays calm, fire up your browser (chrome browser in my case), type 127.0.0.1:8081 in the browser, and witness the pact broker coming up on your browser.

The default port for the pact broker’s image is 80, but I had to change that to something else because I already had http server up and running at the port 80 and had to avoid the port conflict.

If you do not have anything up and running, you should change the port section in the docker-compose to “80:80” from “8081:80”