Deployment guide

Buildfarm

Overview

Bazel Buildfarm is an open-source remote build cache and remote execution service that implements Bazel's Remote Execution API (REAPI). When your Bazel builds point at the farm, build actions are cached centrally and executed on the farm's worker instead of on every developer machine and CI runner. A shared cache and offloaded compilation make incremental builds faster and CI cheaper and more consistent.

The SecureAnyCloud image delivers a complete single-node farm, fully installed and wired together, so a working Remote Execution endpoint is reachable within minutes of launch. Buildfarm is a gRPC API service with no web UI. You drive it from Bazel by pointing --remote_executor and --remote_cache at it. This guide uses the bazel client (through bazelisk) to demonstrate a real build offloaded to the farm.

What you get:

  • Bazel Buildfarm (verified at 2.17.1) as the official buildfarm-server and buildfarm-worker container images, run under systemd
  • A Redis SHARD backplane, bound to loopback and protected by a per-VM secret. Buildfarm 2.x is a sharded architecture, so it needs a Redis backplane that holds the content-addressable storage, the action cache and the execution queue
  • buildfarm-server.service exposing the Remote Execution API on :8980, the endpoint your clients dial, and buildfarm-worker.service executing actions on :8981
  • No default secret. A unique backplane secret is generated on each VM's first boot and written to a root-only file. Redis is bound to the loopback interface and protected by that secret. No two VMs share a credential, and none is baked into the image
  • buildfarm-firstboot.service, which mints the per-VM backplane secret, renders the config and writes the fail-secure bootstrap marker
  • Fail secure. The server and worker both carry a bootstrap gate that clears only after first boot has minted the per-VM secret and rendered the configuration. If first boot were interrupted, the farm would not serve, rather than coming up with a build-time or default secret
  • A firewall guard that keeps the internal worker port and the backplane off the public network while leaving the server endpoint your build fleet uses reachable
  • Ubuntu 24.04 LTS base, patched at build time, with a swapfile sized for the two JVMs and Redis
  • 24/7 SecureAnyCloud support with a 24-hour response SLA

Prerequisites

You need an active Azure subscription, an SSH key pair, and a VNet with a subnet.

The recommended VM size is Standard_B2s (2 vCPU, 4 GB RAM) for evaluation and small teams. Choose Standard_D4s_v5 or larger for busy CI fleets that run many parallel actions. The worker executes actions on the node, so more vCPU and RAM directly raise how much work the farm can run at once.

1

Deploy from the Azure Portal

Search the Marketplace for Bazel Buildfarm on Ubuntu 24.04 and choose your VM size.

Attach a network security group (NSG) that allows TCP 22 (SSH) from your management network and TCP 8980 (the Remote Execution endpoint) from the build and CI machines that will use the farm.

Clients need to reach only the server port 8980. The worker port 8981 and the Redis backplane are internal, and the built-in firewall guard keeps them off the public network.

2

Deploy from the Azure CLI

RG="buildfarm-prod"; LOCATION="eastus"; VM_NAME="buildfarm-01" IMAGE_URN="sac1647283583153:buildfarm-ubuntu-24-04:default:latest" SSH_KEY="$(cat ~/.ssh/id_rsa.pub)" az group create --name "$RG" --location "$LOCATION" az network vnet create -g "$RG" --name bf-vnet --address-prefix 10.90.0.0/16 --subnet-name bf-subnet --subnet-prefix 10.90.1.0/24 az network nsg create -g "$RG" --name bf-nsg az network nsg rule create -g "$RG" --nsg-name bf-nsg --name allow-ssh --priority 100 \
  --source-address-prefixes "<your-mgmt-cidr>" --destination-port-ranges 22 --access Allow --protocol Tcp az network nsg rule create -g "$RG" --nsg-name bf-nsg --name allow-farm --priority 110 \
  --source-address-prefixes "<your-build-cidr>" --destination-port-ranges 8980 --access Allow --protocol Tcp
# Accept the Marketplace terms once per subscription (required before the first CLI deploy)
az vm image terms accept --urn sac1647283583153:buildfarm-ubuntu-24-04:default:latest
az vm create -g "$RG" --name "$VM_NAME" --image "$IMAGE_URN" \
  --size Standard_B2s --storage-sku StandardSSD_LRS \
  --admin-username azureuser --ssh-key-values "$SSH_KEY" \
  --vnet-name bf-vnet --subnet bf-subnet --nsg bf-nsg --public-ip-sku Standard
3

Connect via SSH

ssh azureuser@<vm-ip>
4

Verify the services and listeners

The farm is three services: the Redis backplane, the Buildfarm server on :8980, and the Buildfarm worker on :8981. Confirm that all three are active, that the server and worker are listening, and that the loopback backplane requires the per-VM secret.

sudo systemctl is-active redis-server buildfarm-server buildfarm-worker ss -tln | grep -E ':8980|:8981' echo "redis (no credential) -> $(redis-cli -h 127.0.0.1 ping 2>&1)"

You should see all three services active and listeners on 8980 and 8981. The unauthenticated Redis ping returns NOAUTH Authentication required, which confirms that the backplane is protected.

5

Run a real build on the farm (remote execution)

Create a small Bazel workspace and build it, pointing Bazel at the local farm. The Buildfarm worker executes the build action instead of this machine, and Bazel reports it as a remote process.

mkdir -p /tmp/buildfarm-demo && cd /tmp/buildfarm-demo printf 'module(name = "demo")\n' > MODULE.bazel printf 'genrule(name = "demo", outs = ["demo.txt"], cmd = "echo built-on-the-farm > $@")\n' > BUILD.bazel echo 7.4.1 > .bazelversion bazelisk build //:demo \
  --remote_executor=grpc://127.0.0.1:8980 \
  --remote_cache=grpc://127.0.0.1:8980 \
  --remote_instance_name=shard cat bazel-bin/demo.txt

Bazel reports the genrule as 1 remote in its process summary (INFO: ... processes: ... 1 remote.). The build completes successfully, and demo.txt holds the output the worker produced.

The first time you run bazelisk, it downloads the pinned Bazel release, so allow a few extra seconds. If the worker has only just started, it can take a few seconds to register with the backplane. Run the build again and the action is dispatched remotely.

6

Rebuild from the remote cache

The farm now stores the action result, so a fresh build of the same target is served from the remote cache instead of being executed again. Clean the local state and build again.

cd /tmp/buildfarm-demo bazelisk clean bazelisk build //:demo \
  --remote_executor=grpc://127.0.0.1:8980 \
  --remote_cache=grpc://127.0.0.1:8980 \
  --remote_instance_name=shard

Bazel now reports 1 remote cache hit in its process summary. This proves that the result came back from the farm instead of being rebuilt. This is how a shared cache speeds up your team: once one machine builds a target, every other machine and CI runner pulls the result from the farm.

7

Point your own project at the farm

Add the farm to your project's .bazelrc, or pass the flags on the command line. The endpoint and instance name for this VM are in the root-only info note:

sudo grep -E '^BUILDFARM_ENDPOINT|^BUILDFARM_INSTANCE_NAME' /root/buildfarm-info.txt

Then, in your project's .bazelrc, point Bazel at the server. Use the VM's reachable address for <vm-ip>:

# .bazelrc — offload build actions to the farm and share the cache build --remote_executor=grpc://<vm-ip>:8980 build --remote_cache=grpc://<vm-ip>:8980 build --remote_instance_name=shard
# optional: keep building locally if the farm is briefly unreachable build --remote_local_fallback

Run any build twice across your fleet. The first run populates the cache and offloads execution, and later builds on any machine reuse the cached results.

For traffic across untrusted networks, restrict the NSG to networks you control and terminate TLS in front of the endpoint. Alternatively, enable Buildfarm's own gRPC TLS (see the Buildfarm documentation).

8

The per-VM backplane secret and security

This VM's first boot generates the backplane secret, writes it to a root-only file, and uses it to protect the loopback Redis backplane. The server and worker are gated on a bootstrap marker that first boot writes only after the secret exists, so the farm is fail secure.

sudo stat -c '%n perms=%a owner=%U:%G' /root/buildfarm-info.txt
PW=$(sudo grep '^BUILDFARM_REDIS_PASSWORD=' /root/buildfarm-info.txt | cut -d= -f2-)
echo "redis (no credential) -> $(redis-cli -h 127.0.0.1 ping 2>&1)"
echo "redis (per-VM secret) -> $(redis-cli -h 127.0.0.1 -a "$PW" ping 2>/dev/null)"

The info note is 0600 root:root. The unauthenticated ping is rejected with NOAUTH, and the per-VM secret returns PONG. An nftables guard drops the internal worker port 8981 and Redis 6379 off-box, while the server endpoint 8980 stays reachable for your clients.

Sizing, persistence and first boot

The worker's content-addressable storage lives on the OS disk under /var/lib/buildfarm/worker with a size cap. Raise the cap or attach a larger disk for bigger build graphs.

Scale the farm by choosing a larger VM size, so that the worker can execute more actions in parallel.

The first-boot service generates the per-VM secret, renders the configuration and writes the fail-secure marker. It then disables itself, so later reboots are unaffected. The OS is patched at build time and ships with unattended security upgrades enabled.

sudo systemctl is-enabled buildfarm-firstboot.service buildfarm-server.service buildfarm-worker.service
sudo docker ps --format ' {{.Names}} {{.Status}}' export DEBIAN_FRONTEND=noninteractive;
sudo apt-get update -y >/dev/null 2>&1 echo "held packages: $(apt-mark showhold | tr '\n' ' ')[none]"

Support

Every SecureAnyCloud deployment includes 24/7 support with a 24-hour response SLA. Contact sales@secureanycloud.com for help with deployment, configuration or scaling.

This is a repackaged open-source software product with additional charges for SecureAnyCloud support services. Bazel and Bazel Buildfarm are trademarks of their respective owners. All product and company names are trademarks or registered trademarks of their respective holders. Use of them does not imply any affiliation with or endorsement by them.

Deploy on Azure

Launch Bazel Buildfarm on Ubuntu 24.04 LTS on Azure with 24/7 support from SecureAnyCloud.

View this image

Need Help?

Our support team is available 24/7.

sales@secureanycloud.com

Deploy on Azure