Why this Bazel reference exists
Why I used the OpenTelemetry Astronomy Shop as a serious Bazel learning lab, what changed in the migration, and which services make this repo a deep polyglot reference.
Why this Bazel reference exists
I did not want another Bazel tutorial that only compiles a tiny toy project. I wanted a real migration reference that reflects the friction people actually face in production: many languages, many toolchains, many packaging styles, CI constraints, and imperfect trade-offs.
That is why I used the OpenTelemetry Astronomy Shop fork as the core lab: a polyglot monorepo where Bazel has to coexist with Docker-based runtime flows, language ecosystems, and team realities.
This work is based on my fork of the OpenTelemetry demo: adamBoualleiguie/opentelemetry-demo-basel-integration.
Why this is a strong Bazel learning ground
| What I needed to learn deeply | Why this repo is ideal |
|---|---|
| Graph modeling across stacks | Go, Node, Python, JVM, .NET, Rust, C++, Ruby, Elixir, PHP, edge proxies, and mobile concerns in one place. |
| Bzlmod and dependency governance | MODULE.bazel and MODULE.bazel.lock are central and evolve with real service work. |
| OCI build policy | Dual build tracks force explicit policy instead of pretending one path can replace everything overnight. |
| CI realism | Tag-routed tests, partial hermeticity, network exceptions, and staged hardening toward blocking gates. |
Before and after: how the project changed
I deliberately kept this migration honest: Bazel adoption is staged, not magic. Some paths remain Dockerfile-driven by policy, and those boundaries are documented.
High-level evolution
- Before: mostly Make + Docker Compose orchestration, language-specific commands, and mixed dependency control.
- Transition: milestone-based rollout (
M0toM5) with explicit task IDs and acceptance criteria. - Current state: Bazel is a serious build/test authority in CI, while OCI policy distinguishes Bazel images from Dockerfile release concerns.
Current service landscape (polyglot table)
| Service / Area | Primary language or runtime | Bazel role in this reference |
|---|---|---|
checkout, product-catalog | Go | Core early migration examples: proto wiring, Gazelle, and first stable service targets. |
payment, frontend | Node / Next.js | Lockfile discipline, runfiles correctness, and practical sandbox constraints. |
recommendation, load-generator | Python | rules_python, pip hubs, image packaging, and CI-reproducible dependency behavior. |
ad, fraud-detection | Java / Kotlin | JVM graph modeling, maven pinning, proto dependencies, and OCI packaging parity decisions. |
accounting, cart | .NET | Host toolchain integration under Bazel orchestration with explicit CI expectations. |
shipping, currency | Rust / C++ | Native toolchain complexity, linking choices, and reproducible build discipline. |
email, flagd-ui, quote | Ruby / Elixir / PHP | Custom packaging flows and pragmatic rules where ecosystem constraints matter. |
frontend-proxy, image-provider | Envoy / nginx configs | Config-as-artifact modeling, bake scripts, and OCI image policy trade-offs. |
My objective for readers
I want this to function as a serious learning reference:
- You can understand Bazel architecture in a non-trivial monorepo.
- You can trace design choices from policy to implementation to CI.
- You can reuse the migration patterns in your own repository without cargo-culting commands.
The table below is the service map: each path shows how the service is built today, how protos are wired in Bazel (M1), and the Bazel support status for that component.
Legend: NS = Not started | P = Proto in Bazel | B = Build | T = Test | I = Image | CI = included in blocking bazel_ci job (tools/bazel/ci/ci_full.sh)
| Path | Language | Build entrypoint (today) | Bazel proto (M1) | Status |
|---|---|---|---|---|
src/accounting | .NET | Dockerfile / dotnet | //pb:demo.proto → src/protos (Bazel) | B/I |
src/ad | Java | Gradle / Dockerfile | //pb:demo_java_grpc | B/I |
src/cart | .NET | Dockerfile / dotnet | //pb:demo.proto → pb/demo.proto in publish tree (Bazel) | B/T/I |
src/checkout | Go | Dockerfile / go | //pb:demo_go_proto_checkout | B/T/I |
src/currency | C++ | Dockerfile / cmake | //pb:demo.proto → genrule copy + proto_library in //src/currency (BZ-092); optional //pb:demo_cpp_grpc for other C++ consumers | B/T/I |
src/email | Ruby | Dockerfile / bundler | — | B/T/I |
src/flagd-ui | Elixir | Dockerfile / mix | — | B/T/I |
src/fraud-detection | Kotlin | Gradle / Dockerfile | //pb:demo_java_grpc | B/I |
src/frontend | TS/Next | Dockerfile / npm | — | B/T/I |
src/frontend-proxy | Envoy | Dockerfile / Bazel baked YAML | — | B/T/I |
src/image-provider | nginx | Dockerfile / Bazel baked nginx.conf | — | B/T/I |
src/kafka | infra | Dockerfile | — | Dockerfile (BZ-110) |
src/llm | Python | Dockerfile | — | B/I |
src/load-generator | Python | Dockerfile | — | B/I |
src/opensearch | infra | Dockerfile | — | Dockerfile (BZ-110) |
src/payment | Node | Dockerfile / npm | — | B/I |
src/product-catalog | Go | Dockerfile / go | //pb:demo_go_proto_product_catalog | B/T |
src/product-reviews | Python | Dockerfile | //pb:demo_py_grpc | B/I |
src/quote | PHP | Dockerfile / Composer | — | B/T/I |
src/react-native-app | TS/RN (Expo) | npm / Gradle (Android only in Bazel) | — | B/T |
src/recommendation | Python | Dockerfile | //pb:demo_py_grpc | B |
src/shipping | Rust | Dockerfile / cargo | — (proto in Bazel TBD) | B/T/I |