When I created my project using Spring Initializr, I wanted to try some integrations that I’ve never used with Spring Boot before, like Google PubSub or Flyway. I also added Postgres and Jooq as a dependency.

So in total, I had two dependencies: PubSub and Postgres, meaning that I would need to run them locally to test the integration.

PubSub

I know three options to run PubSub locally:

Run gcloud PubSub emulator. Then manually create all the topics and subscriptions that you need

gcloud components install pubsub-emulator

...

gcloud beta emulators pubsub start --project=PUBSUB_PROJECT_ID

Run a containerized PubSub emulator. You can pass topics and subscriptions as environment variables and they will be created when the container starts.

docker run --rm -ti -p 8681:8681 messagebird/gcloud-pubsub-emulator:latest

Run PubSub emulator in Kubernetes. It uses the containerized PubSub emulator and it’s wrapped in a Kubernetes Service so that it’s easier to consume.

apiVersion: apps/v1

kind: Deployment

metadata:

name: pubsub

labels:

app: pubsub

spec:

replicas: 1

selector:

matchLabels:

app: pubsub

template:

metadata:

labels:

app: pubsub

spec:

containers:

- name: pubsub

image: messagebird/gcloud-pubsub-emulator:latest

env:

- name: PUBSUB_PROJECT1

value: "PROJECTID,TOPIC1:SUBSCRIPTION1,TOPIC2:SUBSCRIPTION2"

ports:

- containerPort: 8681

And here’s the service:

apiVersion: v1

kind: Service

metadata:

name: pubsub

labels:

app: pubsub

spec:

externalName: pubsub

type: NodePort

ports:

- name: pubsub

port: 8681

nodePort: 30100

selector:

app: pubsub

Postgres

I’ll mention at least three options to run PubSub locally:

Old-school: Install Postgres — Google how to do it, there’s an installer for that.

Run a containerized Postgres instance:

docker run --name some-postgres -e POSTGRES_PASSWORD=mysecretpassword -d postgres

Run Postgres in Kubernetes: This one is a little bit more complex since I don’t want my DB to lose all the data when I restart a pod, right? So that’s why I need to define a volume and storage.

Why Kubernetes?

Running N different containers with their IPs and Ports, in N terminals and making sure they all point to the correct address and port was way too painful. That’s why I decided to go with Kubernetes instead of Docker: when you deploy in Kubernetes you have access to a built-in DNS service or environment variables with addresses and ports for all the services that you deployed.