Skip to main content

Local Development

Prerequisites

  • Docker (for Spanner/Firebase emulators and service containers)
  • Bazel (builds all services)
  • pnpm (for frontend websites)
  • Python 3 (for dev scripts)

Quick Start

# Start all backend services (Spanner emulator + Firebase emulator + 6 services)
./scripts/dev.sh services

# Start everything including admin portal frontend
./scripts/dev.sh all

# Stop all services
./scripts/dev.sh stop

What dev.sh services Does

  1. Starts Spanner emulator: gRPC on host port 9110, REST on host port 9120
  2. Starts Firebase Auth emulator: port 9199, UI at port 4100
  3. Builds OCI images: bazel build for all 6 services
  4. Loads images into Docker: incremental (skips unchanged images)
  5. Starts docker-compose: all 6 services with host networking
  6. Health polls: waits up to 60s for all services to report healthy

Service Ports

ServiceHTTPPGAdapterDocker Container
auth80819432dev-gateway-auth
processing80829433dev-gateway-processing
management80839434dev-gateway-management
online-txn80849435dev-gateway-online-txn
merchant-onboarding80859436dev-gateway-merchant-onboarding
status8086-dev-gateway-status

Emulators

ServicePortNotes
Spanner (gRPC)9110SPANNER_EMULATOR_HOST=localhost:9110
Spanner (REST)9120
Firebase Auth9199FIREBASE_AUTH_EMULATOR_HOST=localhost:9199
Firebase UI4100Browser-accessible at http://localhost:4100

Dev Commands

./scripts/dev.sh all # Everything
./scripts/dev.sh services # Backend services only
./scripts/dev.sh portal # Admin Portal frontend (Vite HMR on :5173)
./scripts/dev.sh infra # Emulators only
./scripts/dev.sh stop # Stop everything
./scripts/dev.sh status # Show what's running
./scripts/dev.sh logs auth # Tail specific service logs

Running Individual Services

# Build and run a single service directly (needs emulators running)
./scripts/dev.sh infra
source scripts/dev.env
bazel run //services/processing:core

Running Tests

# All tests
bazel test //...

# Single test
bazel test //services/processing:subscription_service_test

# Test with output
bazel test //services/processing:subscription_service_test --test_output=all

Frontend Development

# Admin Portal dev server (hot reload)
bazel run //websites/admin-portal:start

# Or directly with pnpm (from websites/admin-portal/)
pnpm dev

When you use the shared local stack from ./scripts/dev.sh, frontend apps talk to the backend services on the docker-mapped host ports (8181-8186). Host-run services should source scripts/dev.env so internal proxy calls use those same mapped ports.

Frontend apps connect to the Firebase Auth emulator in local dev when VITE_FIREBASE_AUTH_EMULATOR_HOST=localhost:9199 is present in the app env file.

Common Issues

IssueFix
Docker not runningStart Docker Desktop or systemctl start docker
Port already in use./scripts/dev.sh stop then retry, or lsof -i :PORT to find process
Stale image./scripts/dev.sh stop && ./scripts/dev.sh services forces rebuild
Spanner emulator won't startCheck Docker is running and port 9110 is free
Firebase emulator port conflictCheck port 9199 is free (lsof -i :9199)