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.

Project context

This work is based on my fork of the OpenTelemetry demo: adamBoualleiguie/opentelemetry-demo-basel-integration.

Loading image...
Loading image...

Why this is a strong Bazel learning ground

What I needed to learn deeplyWhy this repo is ideal
Graph modeling across stacksGo, Node, Python, JVM, .NET, Rust, C++, Ruby, Elixir, PHP, edge proxies, and mobile concerns in one place.
Bzlmod and dependency governanceMODULE.bazel and MODULE.bazel.lock are central and evolve with real service work.
OCI build policyDual build tracks force explicit policy instead of pretending one path can replace everything overnight.
CI realismTag-routed tests, partial hermeticity, network exceptions, and staged hardening toward blocking gates.

Before and after: how the project changed

Loading image...
No fake simplification

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 (M0 to M5) 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 / AreaPrimary language or runtimeBazel role in this reference
checkout, product-catalogGoCore early migration examples: proto wiring, Gazelle, and first stable service targets.
payment, frontendNode / Next.jsLockfile discipline, runfiles correctness, and practical sandbox constraints.
recommendation, load-generatorPythonrules_python, pip hubs, image packaging, and CI-reproducible dependency behavior.
ad, fraud-detectionJava / KotlinJVM graph modeling, maven pinning, proto dependencies, and OCI packaging parity decisions.
accounting, cart.NETHost toolchain integration under Bazel orchestration with explicit CI expectations.
shipping, currencyRust / C++Native toolchain complexity, linking choices, and reproducible build discipline.
email, flagd-ui, quoteRuby / Elixir / PHPCustom packaging flows and pragmatic rules where ecosystem constraints matter.
frontend-proxy, image-providerEnvoy / nginx configsConfig-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:

  1. You can understand Bazel architecture in a non-trivial monorepo.
  2. You can trace design choices from policy to implementation to CI.
  3. 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)

PathLanguageBuild entrypoint (today)Bazel proto (M1)Status
src/accounting.NETDockerfile / dotnet//pb:demo.protosrc/protos (Bazel)B/I
src/adJavaGradle / Dockerfile//pb:demo_java_grpcB/I
src/cart.NETDockerfile / dotnet//pb:demo.protopb/demo.proto in publish tree (Bazel)B/T/I
src/checkoutGoDockerfile / go//pb:demo_go_proto_checkoutB/T/I
src/currencyC++Dockerfile / cmake//pb:demo.proto → genrule copy + proto_library in //src/currency (BZ-092); optional //pb:demo_cpp_grpc for other C++ consumersB/T/I
src/emailRubyDockerfile / bundlerB/T/I
src/flagd-uiElixirDockerfile / mixB/T/I
src/fraud-detectionKotlinGradle / Dockerfile//pb:demo_java_grpcB/I
src/frontendTS/NextDockerfile / npmB/T/I
src/frontend-proxyEnvoyDockerfile / Bazel baked YAMLB/T/I
src/image-providernginxDockerfile / Bazel baked nginx.confB/T/I
src/kafkainfraDockerfileDockerfile (BZ-110)
src/llmPythonDockerfileB/I
src/load-generatorPythonDockerfileB/I
src/opensearchinfraDockerfileDockerfile (BZ-110)
src/paymentNodeDockerfile / npmB/I
src/product-catalogGoDockerfile / go//pb:demo_go_proto_product_catalogB/T
src/product-reviewsPythonDockerfile//pb:demo_py_grpcB/I
src/quotePHPDockerfile / ComposerB/T/I
src/react-native-appTS/RN (Expo)npm / Gradle (Android only in Bazel)B/T
src/recommendationPythonDockerfile//pb:demo_py_grpcB
src/shippingRustDockerfile / cargo— (proto in Bazel TBD)B/T/I