Google Cloud Pub/Sub compatibility for Zyvor Relay.
Speak familiar Pub/Sub gRPC and REST. The gateway handles translation, TLS, metrics, and — with RELAY_BACKEND=relay-events — forwards every publish to Relay's real POST /v1/events API.
Google SDK / curl relay-pubsub Zyvor Relay
───────────────── ────────────── ───────────
Publish "irrigation. → topic = event type → Accept
required" self-signed HTTPS Notify · Act
Pull / StreamingPull ← action queue ← /v1/actions
Images: ghcr.io/zyvorai/relay-pubsub:0.4.0 · ghcr.io/zyvorai/relay-pubsub-console:0.4.0
Current release: v0.4.0 · Image: ghcr.io/zyvorai/relay-pubsub:0.4.0
Relay's API is event-lifecycle shaped — not topics and subscriptions. But your edge apps, SDKs, and ops tooling speak Google Pub/Sub.
relay-pubsub sits in the middle: full Publisher/Subscriber surface on the front, RelayBackend on the back. Production path: relay-events → Relay's shipped API. Demo path: memory → instant local round-trip.
Pair with relay-edge for stamped farm events and industrial simulators that publish through the same gateway.
Runs on edge Linux (systemd), Kubernetes / k3s, or Docker.
relay-pubsub is a narrow, open-source (Apache-2.0) protocol compatibility
gateway — it exists purely so Google Pub/Sub SDKs/tooling can talk to
Zyvor Relay's event-lifecycle API. It is not a general message broker
(not a NATS/RabbitMQ/Kafka replacement) and not a standalone product —
the relay-events production backend requires Relay itself to be running;
only the memory backend works standalone, for demos/CI.
If you're evaluating this against the real Google Cloud Pub/Sub service or its official emulator: relay-pubsub implements the same gRPC/REST surface (topics/subscriptions, Publish, Pull, StreamingPull, Ack, Seek, Snapshots, IAM subset, SchemaService) but routes messages into Relay's durable event system, not Google's infrastructure — use it when you want Pub/Sub-shaped client code talking to a self-hosted, offline-capable edge stack instead.
Maturity, stated honestly: current release is v0.4.0. The README's own "Production boundary" section states this gateway "targets Google Pub/Sub compatibility through v0.3... Multi-replica durable cursors still belong in Relay core" — i.e. HA/durability guarantees beyond a single replica are not yet a property of this gateway itself.
New here? docs/FAQ.md covers licensing, support, and
scope questions. Troubleshooting lives in
docs/DEPLOYMENT.md.
docker compose up --build
bash scripts/smoke.sh # curl -k, self-signed TLSOr pull the release image:
docker pull ghcr.io/zyvorai/relay-pubsub:0.4.0
docker run --rm -p 8080:8080 -p 50051:50051 \
-e RELAY_BACKEND=memory ghcr.io/zyvorai/relay-pubsub:0.4.0Install all targets → docs/INSTALL.md
How to test → docs/TESTING.md
New here? → docs/GETTING_STARTED.md
| Guide | What's inside |
|---|---|
| ❓ FAQ | Licensing, support, scope questions |
| 📖 Docs hub | Index of everything |
| 📦 Installation | Docker, GHCR, Cargo, systemd, Kubernetes, console |
| 🧪 Testing | Smoke, conformance, Relay, console, release checklist |
| 🚀 Getting started | First publish / pull |
| ⚡ Relay events backend | Production backend, catalogs, actions |
| 🚢 Deployment | Lab notes, systemd + k8s detail |
| 🏗 Architecture | Boundaries, HA, tenant model |
| 🔎 Filters & schemas | Attribute filters, schema publish, CloudEvents |
| 📝 Changelog | Release notes |
| 📜 Native API (legacy) | Invented http backend contract |
| Backend | Relay needed? | Use case |
|---|---|---|
memory |
No | CI, k3s smoke, demos, offline edge |
http |
Yes (invented API) | Legacy — prefer relay-events |
relay-events |
Yes (real API) | Fasal, relay-edge, production |
export RELAY_BACKEND=relay-events
export RELAY_BASE_URL=https://relay.example.com:8443
export RELAY_AUTH_TOKEN=<jwt>
export RELAY_TLS_INSECURE=1 # if Relay uses self-signed TLS
cargo runGoogle-compatible surface (click to expand)
gRPC: Create/Update/Get/List/Delete topics & subscriptions, Publish, Pull, StreamingPull, Acknowledge, ModifyAckDeadline, Seek (time + snapshot), Snapshots, ModifyPushConfig, ListTopicSubscriptions, IAM subset, SchemaService.
REST: Matching /v1/projects/... admin + data plane, including pagination (pageSize / pageToken), PATCH updates, snapshots, schemas, IAM.
Semantics (memory / relay-events local store): explicit ACK, NACK via zero deadline, DLQ after max attempts, ordering keys, exactly-once ack leases, retry backoff, timestamp + snapshot seek, push dispatcher, optional durable JSON state (PUBSUB_PERSIST), Prometheus metrics, attribute filters, schema-bound publish, messageId dedup, CloudEvents attribute projection.
Ops: /admin/v1/inventory, /admin/v1/logs, /admin/v1/push-config, product console (Incoming / Outgoing / Stored / Logs).
gRPC and REST are TLS-only. First start generates a self-signed cert at /var/lib/relay-pubsub/tls/ (configurable). Set PUBSUB_TLS_SAN before first start to embed your host IP and service DNS names.
curl -k https://localhost:8080/healthz
grpcurl -insecure localhost:50051 listSee Getting started for the PUBSUB_EMULATOR_HOST caveat with Google's plaintext emulator mode.
| Target | Command |
|---|---|
| Linux host (systemd) | bash scripts/deploy-remote.sh <HOST> <USER> --quick |
| Ops console | bash scripts/deploy-console-remote.sh <HOST> <USER> |
| Local k3s | bash deploy/scripts/deploy-k3s.sh |
| Helm | helm upgrade --install … deploy/helm/relay-pubsub |
| k8s + relay-edge | From relay-edge: ./deploy/scripts/deploy-k8s-remote.sh <HOST> |
| GHCR | docker pull ghcr.io/zyvorai/relay-pubsub:0.4.0 |
Verify:
BASE=https://<host>:8081 bash scripts/smoke.sh
BASE=https://<host>:8081 bash scripts/conformance-smoke.sh
BASE=https://<host>:8081 bash scripts/smoke-relay-events.shFull install + test guides → INSTALL · TESTING · DEPLOYMENT
Stack integration test: relay-edge TEST_RESULTS.md (2026-08-28 — all PASS, includes this gateway).
| Project | Role |
|---|---|
| relay | Control plane |
| relay-pubsub (this repo) | Pub/Sub gateway |
| relay-edge | Farm domain + simulators |
This gateway targets Google Pub/Sub compatibility through v0.3 (updates, snapshots, push, IAM subset, schemas, ordering, exactly-once leases, durable local state, inventory + logs). Multi-replica durable cursors still belong in Relay core. See the compatibility roadmap.
This repository is licensed under the Apache License, Version 2.0. You may use, modify, and run it for personal, lab, and commercial production use at no charge, subject to Apache-2.0 (preserve notices / NOTICE where required).
Production support, SLAs, and Zyvor Enterprise products are licensed separately. Contact sales@zyvor.dev or see zyvor.dev.