diff --git a/docker-compose.yaml b/docker-compose.yaml
new file mode 100644
index 0000000..3005d5a
--- /dev/null
+++ b/docker-compose.yaml
@@ -0,0 +1,37 @@
+version: "3"
+
+services:
+  postgres:
+    image: postgres
+    healthcheck:
+      test: psql postgres --command "select 1" -U postgres
+    volumes:
+      - postgres-volume:/var/lib/postgresql/data
+    environment:
+      POSTGRES_USER: postgres
+      POSTGRES_PASSWORD: password
+      POSTGRES_DB: postgres
+
+  pact-broker:
+    image: pactfoundation/pact-broker:latest
+    ports:
+      - "9292:9292"
+    depends_on:
+      - postgres
+    environment:
+      PACT_BROKER_PORT: '9292'
+      PACT_BROKER_DATABASE_URL: "postgres://postgres:password@postgres/postgres"
+      PACT_BROKER_LOG_LEVEL: INFO
+      PACT_BROKER_SQL_LOG_LEVEL: DEBUG
+      # PACT_BROKER_DATABASE_CONNECT_MAX_RETRIES is only needed for docker-compose
+      # because the database takes longer to start up than the puma process
+      # Should not be needed in production.
+      PACT_BROKER_DATABASE_CONNECT_MAX_RETRIES: "5"
+      # The list of allowed base URLs (not setting this makes the app vulnerable to cache poisoning)
+      # This list allows the app to be addressed from the host and from within another docker container correctly
+      # Ngnix config below makes the app accessible on ports 443 and 80, while the Ruby application itself runs on port 9292
+      PACT_BROKER_BASE_URL: 'https://localhost http://localhost http://localhost:9292 http://pact-broker:9292 https://host.docker.internal http://host.docker.internal http://host.docker.internal:9292'
+
+volumes:
+  postgres-volume:
+
diff --git a/src/test/java/de/rpr/pactexample/PactProviderJUnit5WithBrokerTest.java b/src/test/java/de/rpr/pactexample/PactProviderJUnit5WithBrokerTest.java
new file mode 100644
index 0000000..f40738b
--- /dev/null
+++ b/src/test/java/de/rpr/pactexample/PactProviderJUnit5WithBrokerTest.java
@@ -0,0 +1,44 @@
+package de.rpr.pactexample;
+
+import au.com.dius.pact.provider.junit5.HttpTestTarget;
+import au.com.dius.pact.provider.junit5.PactVerificationContext;
+import au.com.dius.pact.provider.junit5.PactVerificationInvocationContextProvider;
+import au.com.dius.pact.provider.junitsupport.Provider;
+import au.com.dius.pact.provider.junitsupport.State;
+import au.com.dius.pact.provider.junitsupport.loader.PactBroker;
+import org.junit.jupiter.api.BeforeEach;
+import org.junit.jupiter.api.TestTemplate;
+import org.junit.jupiter.api.extension.ExtendWith;
+import org.junitpioneer.jupiter.SetSystemProperty;
+import org.springframework.boot.test.context.SpringBootTest;
+import org.springframework.boot.test.web.server.LocalServerPort;
+
+@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT)
+@Provider("UserServiceJUnit5")
+@PactBroker(url = "http://localhost:9292")
+@SetSystemProperty.SetSystemProperties({
+        @SetSystemProperty(key = "pact.verifier.publishResults", value = "true"),
+        @SetSystemProperty(key = "pact.provider.version", value = "current")
+})
+public class PactProviderJUnit5WithBrokerTest {
+
+    @LocalServerPort
+    int port;
+
+    @BeforeEach
+    public void setup(PactVerificationContext context) {
+        context.setTarget(new HttpTestTarget("localhost", port));
+    }
+
+    // see: https://docs.pact.io/getting_started/provider_states
+    @State("A running user service")
+    void setupUserService() {
+        // no state setup ATM
+    }
+
+    @TestTemplate
+    @ExtendWith(PactVerificationInvocationContextProvider.class)
+    void pactVerificationTestTemplate(PactVerificationContext context) {
+        context.verifyInteraction();
+    }
+}