Skip to content
Updated Jun 9, 2026

Infrastructure: Environments and Topology

Olly runs the same service code in three environments. Each environment has different backing services and operational characteristics. This page is the entry point; follow the per-environment pages for details.


Environments at a glance

EnvironmentPurposeTopologyDoc
Local devSingle-developer hacking on servicesDocker Compose + Tilt + Go binaries from go.work, all on one workstationLocal Development
Shared dev (Hetzner)Team-shared dev clusterFour Hetzner VMs (dev-1, dev-2, ci, uat) on a VPC at 10.0.1.0/24; mosh/ssh access(see below - Shared dev)
Production (GCP)Customer-facingGKE Standard + Cloud SQL + Memorystore + Strimzi + GCLB in olly-prod project, europe-west2Production (GCP)

Local dev - summary

Docker Compose brings up the infrastructure stack (Postgres, Kafka via Redpanda, Keycloak, OpenSearch, Temporal, OpenBao, OTel). Go services run from the go.work workspace via make run-all, or hot-reloaded by Tilt. Every domain points to *.localhost aliases routed through APISIX. See Local Development for prerequisites and a full step-by-step.


Shared dev (Hetzner) - summary

Four Hetzner VMs in a single VPC (10.0.1.0/24). dev-1 hosts services currently under active development; dev-2 hosts shared infra. CLAUDE.md in the repo root is the authoritative description; this page summarises.

HostPublic IPVPC IPRole
dev-1135.181.39.2310.0.1.1Active-dev workloads: triage, open-webui, nhs111, nginx (TLS termination for *.dev.hiolly.com)
dev-2204.168.197.17510.0.1.2Shared infra: postgres, valkey, kafka, opensearch, keycloak, temporal, openbao, otel, langfuse, mirth
ci204.168.206.22310.0.1.3CI runners + scrape pool
uat204.168.192.3210.0.1.4Novu (notifications) + UAT-clone of Go stack

Cross-host wiring uses VPC IPs (10.0.1.2:<port>), never container hostnames. New shared-infra services bind to 10.0.1.2:<port>:<port> not 127.0.0.1:.


Production (GCP) - summary

GCP migration is in flight. The production data plane is live (Cloud SQL, Memorystore, GKE, Strimzi Kafka). Application workloads still run on shared dev and migrate to GKE per the sub-project roadmap. See Production (GCP) for the GCP target architecture and /gcp/MIGRATION_STATUS.md for current cutover state.

LayerGCP serviceStatus (2026-06)
ComputeGKE Standard private cluster olly-prod-ew2 (europe-west2)live
PostgresCloud SQL prod-pg-16 (PG16, regional HA, CMEK)22/22 DBs migrated
CacheMemorystore Valkey prod-valkey (BASIC, TLS+AUTH)live, empty (source had 0 keys)
KafkaStrimzi 4.0 KRaft on GKElive, 8 topics
SearchOpenSearch helm on GKEup, indexes regenerating
SecretsGCP Secret Managerreplacing OpenBao
GatewayGCLB + Cloud Armorreplacing APISIX (sub-project #5)
DNS / TLSCloud DNS + Google-managed certsreplacing Let's Encrypt (sub-project #5)
ObservabilityCloud Logging + Managed Prometheus (interim); Tempo/Loki/Grafana planned for sub-project #6partial

Backing-services parity

What's the same across environments and what differs:

ConceptLocal devShared dev (Hetzner)Production (GCP)
Postgresdocker-compose postgres:16dev-2 olly-postgres @ 10.0.1.2:5432Cloud SQL prod-pg-16 @ 10.10.49.2
Cachedocker-compose valkey:7dev-2 olly-valkey @ 10.0.1.2:16379Memorystore Valkey @ 10.10.48.3:6378
Kafkadocker-compose Redpandadev-2 olly-kafka @ 10.0.1.2:9092Strimzi on GKE
Keycloakdocker-compose keycloak:24dev-2 olly-keycloak :8093GKE deploy in sub-project #4
Searchdocker-compose OpenSearchdev-2 olly-opensearch @ 10.0.1.2:9200OpenSearch helm on GKE
Temporaldocker-composedev-2 olly-temporal :7233GKE deploy in sub-project #4
Secretsdocker-compose OpenBaodev-2 olly-openbao :8200GCP Secret Manager
Gatewaydocker-compose APISIXdev-1 nginx + APISIXGCLB + Cloud Armor
Maildocker-compose Mailpitdev-2 olly-mailpit :8025SES via Novu integration
Observabilitydocker-compose OTel + Jaegerdev-2 OTel + Tempo + Loki + GrafanaCloud Logging + Managed Prometheus (interim)
Notificationsdirect Novu (uat)dev-1 nginx proxies to uat NovuGKE Novu (sub-project #4)

What changes per environment

  • Auth: local dev uses a permissive Keycloak realm seeded by make local-up; shared dev + prod use the canonical olly-members / olly-providers / olly-internal realms.
  • TLS: local dev is HTTP-only (.localhost); shared dev uses Let's Encrypt via nginx; prod uses Google-managed certs via GCLB.
  • Network: local dev is loopback; shared dev uses Hetzner VPC; prod uses Google VPC prod-vpc-ew2 + Cloud NAT for egress.
  • Observability: local dev logs to stdout + local Jaeger; shared dev to dev-2 Grafana stack; prod to Cloud Logging + Managed Prometheus.

When NOT to use which environment

  • Local dev: solo iteration, no shared dependencies on others' work.
  • Shared dev: cross-service integration, peer review, demo to non-engineers.
  • Production: customer-facing only - never demo from prod.

Olly Health Insurance Platform