Deterministic builds with go + bazel + grpc + docker

Deterministic container images for gRPC+golang bazel.

The following sample will build a golang gRPC client/server and then embed the binaries into container images.

These images are will have a consistent image hash no matter where it is built.

For reference, see:

To run this sample, you will need bazel installed

Build Image

Note, the bazel base image specifies the image+hash so your’e starting off from a known state:

  • WORKSPACE

Check Image

Inspect the image thats generated…these wil be the same no matter where you generate the images

(optional) gRPC Client/Server

(why not?…you built it already, give it a shot)

docker run -p 50051:50051 bazel/greeter_server:greeter_server_image
docker run --net=host bazel/greeter_client:greeter_client_image

Specify docker image

You can specify a repo prefix by setting the repository command here. In the case below, its on dockerhub as handle salrashid123

container_image(
name = "greeter_server_image",
base = "@alpine_linux_amd64//image",
entrypoint = ["/server"],
files = [":server"],
repository = "salrashid123"
)

on push to dockerhub

  • Client
$ docker push salrashid123/greeter_server:greeter_server_image
a1852e9ff2e7: Pushed
greeter_server_image: digest: sha256:e3e95e8f07b552ee2f60aaf6308b75ee660e24ff58d3a2b25be26f53476cde87 size: 738

On any other machine pull the image and inspect

$ docker inspect salrashid123/greeter_server@sha256:e3e95e8f07b552ee2f60aaf6308b75ee660e24ff58d3a2b25be26f53476cde87
[
{
"Id": "sha256:7ea0fc3e14c0d0cfdd8048f5ddd19566a1b78f822658b8c5318c14241340a982",
"RepoTags": [
"bazel/greeter_server:greeter_server_image",
"salrashid123/greeter_server:greeter_server_image"
],
"RepoDigests": [
"salrashid123/greeter_server@sha256:e3e95e8f07b552ee2f60aaf6308b75ee660e24ff58d3a2b25be26f53476cde87"
],
...

Cloud Build

You can use Cloud Build to create the image by using the bazel builder and specifying the repository path to export to. In the sample below, the repository is set o google container registry:

container_image(
name = "greeter_server_image",
base = "@alpine_linux_amd64//image",
entrypoint = ["/server"],
files = [":server"],
repository = "gcr.io/mineral-minutia-820"
)

Then on the same system that it was built and pushed:

Thats about it…you’ve now got deterministic builds…now well…time to learn bazel!

TODOs:

  • use gazelle for dependencies bazel run //:gazelle -- update-repos -from_file=examples/greeter_server/go.mod

--

--

--

A collection of technical articles and blogs published or curated by Google Cloud Developer Advocates. The views expressed are those of the authors and don't necessarily reflect those of Google.

Recommended from Medium

The State of Ruby on Rails Today

ruby on rails hero image laptop

via Tumblr http://bit.ly/2kcraGv

Deploying Multi-Node Kubernetes Cluster on AWS Using Ansible Automation

聊天機器人學習筆記目錄(Dialogflow,Chatfuel,manychat)

Introducing Care + Code

DRY — an Alternate Command Line Tool for Docker

Top 4 offshore software development best practices

Applying Android Architecture component to your next Android project

Get the Medium app

A button that says 'Download on the App Store', and if clicked it will lead you to the iOS App store
A button that says 'Get it on, Google Play', and if clicked it will lead you to the Google Play store
salmaan rashid

salmaan rashid

More from Medium

Distributed Locust Testing on Google Kubernetes Engine (GKE)

Scraping Prometheus Metrics from Amazon ECS

Customized queue and retry mechanism with Google Cloud PubSub using Go

Deploy Socket.io to Kubernetes - Part 2: Infrastructure