Bazel Buildfarm on AWS User Guide
Overview
This guide covers the deployment and use of Bazel Buildfarm on AWS using cloudimg's preconfigured Amazon Machine Image. Bazel Buildfarm is an open source remote build cache and remote execution service that implements Bazel's Remote Execution API (REAPI). Point your Bazel builds at it and actions are cached and executed on the farm instead of on every developer laptop and CI runner, so a shared content-addressable cache and offloaded compilation make builds dramatically faster and CI cheaper.
The cloudimg image ships the free and open source, Apache-2.0 licensed Bazel Buildfarm (bazelbuild/buildfarm 2.17.1), run the officially supported way as the upstream container images, as a complete single-node farm: three managed services on one instance.
- A Redis SHARD backplane bound to the loopback interface (Buildfarm 2.x is a sharded architecture, so Redis is required and is configured for you).
- A Buildfarm server that exposes the Remote Execution API on gRPC port 8980 - the endpoint your build clients dial.
- A Buildfarm worker on gRPC port 8981 that executes actions.
The content-addressable cache store lives on a dedicated, independently-resizable EBS data volume mounted at /var/lib/buildfarm, kept off the OS disk. Nothing ships with a known credential: a unique Redis backplane secret is generated on each instance at first boot, and a fail-secure gate stops the server and worker starting until that secret exists, so the farm never comes up with a build-time or default secret. Backed by 24/7 cloudimg support.
Bazel and Bazel Buildfarm are trademarks of their respective owners. This image is produced by cloudimg and is not affiliated with, endorsed by, or sponsored by them. It ships the free and open source Apache-2.0 licensed software, unmodified.

Before you start: the Remote Execution endpoint is a privileged compute plane
This is the single most important thing to know before you use the farm, so it is stated first rather than buried.
The Buildfarm Remote Execution API on port 8980 runs arbitrary build actions that clients submit - that is what remote execution is. An unauthenticated, world-open Remote Execution endpoint is therefore a public remote-code-execution cluster. Treat 8980 as a privileged compute plane.
For that reason this image ships its security group with only SSH (port 22) open. Port 8980 is not open to the world. You deliberately open it only to the machines that should reach it:
- In the EC2 console, open the instance's security group.
- Add an inbound rule: Custom TCP, port 8980, source set to your build fleet's CIDR (your CI runners and/or developer network) - never
0.0.0.0/0.
If you also want the worker reachable for a multi-node farm later, keep in mind the built-in nftables guard drops the internal worker port 8981 and Redis 6379 off-box by design; a single-node farm needs neither exposed.
Connecting to your instance
Connect over SSH as the default login user for your AMI variant:
| OS variant | SSH login user | Example |
|---|---|---|
| Ubuntu 24.04 | ubuntu |
ssh -i your-key.pem ubuntu@<instance-public-ip> |
Once connected, everything below is run on the instance.
Retrieve your farm endpoint and details
On first boot the image resolves this instance's address and writes a root-only info file. Read it with:
sudo cat /root/buildfarm-info.txt
It contains your farm endpoint (grpc://<instance-ip>:8980), the Remote Execution instance name (shard), and the internal Redis backplane secret (used for on-box administration only - Redis is bound to loopback and never exposed).
Check the three services and their listeners at any time:
systemctl status buildfarm-server buildfarm-worker redis-server
ss -tln | grep -E ':8980|:8981|:6379'
The server listens on 8980, the worker on 8981, and Redis on 127.0.0.1:6379 (loopback only).
Point your Bazel client at the farm
After you have opened port 8980 to your build clients (see above), point Bazel at the farm from any client machine. Add these flags to your bazel build / bazel test invocation, or put them in your project's .bazelrc:
bazel build //your:target \
--remote_executor=grpc://<public-ip>:8980 \
--remote_cache=grpc://<public-ip>:8980 \
--remote_instance_name=shard
--remote_executor offloads action execution onto the worker; --remote_cache shares the content-addressable cache so no client rebuilds what another already built. The first build populates the cache; subsequent builds of unchanged targets are served as remote cache hits.
Prove the farm executes and caches actions
The image ships a self-contained proof you can run on the instance at any time. It runs a real Bazel build against the local farm, forces remote execution on the first pass, and asserts a remote cache hit on the second:
sudo /usr/local/sbin/buildfarm-proof.sh 127.0.0.1
A healthy farm prints FARM_PROOF_OK (remote execution + remote cache hit).

Security model
- No default secret. The Redis backplane password that protects the cache store and the execution queue is generated uniquely on each instance's first boot, stored 0600 root-only in
/root/buildfarm-info.txt, and never shipped in the image. A fail-secure bootstrap gate stops the server and worker starting until that per-instance secret exists. - Redis is loopback-only and authenticated. An unauthenticated
redis-cliconnection is rejected withNOAUTH; only the per-instance secret authenticates. - The Remote Execution endpoint is closed by default. The shipped security group opens only SSH; you scope 8980 to your build fleet. A defense-in-depth nftables guard additionally drops the internal worker port 8981 and Redis 6379 off-box.
- Encryption at rest. The dedicated cache data volume at
/var/lib/buildfarmcan use AWS EBS encryption - enable it when launching or use encrypted snapshots.

The cache data volume
The Buildfarm worker's content-addressable cache and Action-Cache filesystem store live on a dedicated EBS volume mounted at /var/lib/buildfarm (ext4, mounted by filesystem UUID). Keep it off the OS disk and resize it independently as your build fleet's cache footprint grows:
df -h /var/lib/buildfarm
findmnt /var/lib/buildfarm
Sizing
The recommended instance type is m5.large (2 vCPU / 8 GB), which comfortably runs the server JVM, the worker JVM, the Redis backplane and a Bazel client for the single-node farm. Scale up for larger action concurrency or a bigger working set.
24/7 cloudimg Support
Technical support by email and live chat covers deployment, endpoint sizing, network scoping of the Remote Execution port, connecting your Bazel clients, cache and worker administration, and troubleshooting. Email support@cloudimg.co.uk or reach us via live chat. For any issues, including requesting refunds, contact support@cloudimg.co.uk.
Licence
Bazel Buildfarm is licensed under Apache-2.0; the licence text is baked into the image at /opt/buildfarm/LICENSE. The Redis backplane is the Ubuntu 24.04 redis-server package (7.0.x), which is BSD-3-Clause. The Buildfarm server and worker run from the official upstream container images bazelbuild/buildfarm-server:2.17.1 and bazelbuild/buildfarm-worker:2.17.1, captured into the AMI so your instance never needs to pull them.