This document explains how to use Bazel to build, test, and deploy the EventStreamMonitor microservices.
Bazel offers several advantages over traditional Docker-based builds:
- Only rebuilds what changed
- Parallel execution of independent tasks
- Smart caching reduces build times significantly
- Same inputs always produce same outputs
- Deterministic builds across different environments
- Eliminates "works on my machine" issues
- Explicit dependency graph
- Automatic dependency resolution
- Prevents circular dependencies
- Builds Python code, proto files, and Docker images
- Consistent build process across all components
- Run tests with proper isolation
- Parallel test execution
- Better test reporting
- Share build cache across team
- Faster CI/CD pipelines
- Reduced build times in cloud environments
-
Install Bazel: Follow instructions at https://bazel.build/install
# macOS brew install bazel # Or download from: https://github.com/bazelbuild/bazel/releases
-
Verify Installation:
bazel version
EventStreamMonitor/
├── WORKSPACE # Bazel workspace configuration
├── BUILD # Root BUILD file
├── .bazelrc # Bazel configuration flags
├── requirements-lock.txt # Pinned Python dependencies
├── common/ # Shared library
│ └── BUILD # (to be created)
├── proto/ # Protocol buffer definitions
│ └── BUILD # (included in root BUILD)
└── services/ # Microservices
├── taskprocessing/
│ └── BUILD # Service BUILD file
├── usermanagement/
│ └── BUILD
├── notification/
│ └── BUILD
└── logmonitor/
└── BUILD
# Build all services
bazel build //services/...
# Build specific service
bazel build //services/taskprocessing:taskprocessing
# Build Docker image
bazel build //services/taskprocessing:taskprocessing_docker# Run a service
bazel run //services/taskprocessing:taskprocessing
# Run with custom arguments
bazel run //services/taskprocessing:taskprocessing -- --port=9092# Run all tests
bazel test //...
# Run tests for specific service
bazel test //services/taskprocessing/...
# Run tests with output
bazel test //services/taskprocessing/... --test_output=all# Build Docker image for a service
bazel build //services/taskprocessing:taskprocessing_docker
# Load image into local Docker (after building)
docker load -i bazel-bin/services/taskprocessing/taskprocessing_docker.tar
# Or use bazel run to build and load
bazel run //services/taskprocessing:taskprocessing_docker -- --norun# See dependencies of a target
bazel query --output=graph //services/taskprocessing:taskprocessing | dot -Tpng > deps.png
# List all targets
bazel query //...
# Find what depends on common library
bazel query 'rdeps(//..., //:common)'You can use Bazel-built images with Docker Compose:
-
Build images with Bazel:
bazel build //services/... bazel build //services/taskprocessing:taskprocessing_docker bazel build //services/usermanagement:usermanagement_docker bazel build //services/notification:notification_docker bazel build //services/logmonitor:logmonitor_docker
-
Load images into Docker:
docker load -i bazel-bin/services/taskprocessing/taskprocessing_docker.tar docker load -i bazel-bin/services/usermanagement/usermanagement_docker.tar docker load -i bazel-bin/services/notification/notification_docker.tar docker load -i bazel-bin/services/logmonitor/logmonitor_docker.tar
-
Tag images (optional):
docker tag bazel/services/taskprocessing:taskprocessing_docker eventstreammonitor-taskprocessing-service:latest
-
Use in docker-compose.yml (update image references)
- Make code changes
- Build only what changed:
bazel build //services/taskprocessing:taskprocessing
- Run service locally:
bazel run //services/taskprocessing:taskprocessing
# Build all services
bazel build //services/...
# Run all tests
bazel test //...
# Build Docker images
bazel build //services/...:..._docker
# Push images (after loading)
docker push your-registry/eventstreammonitor-taskprocessing-service:latest# Verbose output
bazel build //services/taskprocessing:taskprocessing --verbose_failures
# See what commands would run (dry run)
bazel build //services/taskprocessing:taskprocessing --nobuild
# Clean build (remove cache)
bazel clean
bazel build //services/taskprocessing:taskprocessingConfigure remote cache in .bazelrc:
build --remote_cache=https://your-cache-server.com
# Use more jobs (parallel builds)
bazel build //... --jobs=16
# Profile build
bazel build //... --profile=profile.json
# View: chrome://tracing -> load profile.jsonUpdate requirements-lock.txt with pinned versions, then:
# Update pip dependencies
bazel sync --only=pip_deps
# Or manually update in WORKSPACE-
"Module not found" errors:
- Check
depsin BUILD files - Ensure imports match package structure
- Run
bazel clean --expungeand rebuild
- Check
-
Proto compilation errors:
- Verify proto file paths in BUILD
- Check proto syntax and imports
-
Docker image build fails:
- Ensure base image is available
- Check file paths in
container_imagerule
-
Slow builds:
- Use remote caching
- Increase
--jobsflag - Check for unnecessary dependencies
- Fine-tune BUILD files for each service's specific needs
- Add test targets using
py_testrules - Set up remote caching for team/CI
- Integrate with CI/CD (GitHub Actions, Jenkins, etc.)
- Create deployment scripts using Bazel-built images