From d890379e63bbdad6187136f15ee66fb2c0db6b97 Mon Sep 17 00:00:00 2001 From: Fletcher Nichol Date: Tue, 20 Jan 2026 11:05:21 -0700 Subject: [PATCH] feat: build service container images from distroless base This change re-introduces container image builds for our core deployed services, namely: - edda - forklift - luminork - pinga - rebaser - sdf - veritech This solution takes a much different approach to how we've built these images in the past. Prior to this change, we've compiled the target binary from scratch in a build container, using the same Nix and Buck2 infrastructure. This proved to be very difficult to initially implement and was hard to maintain it. Furthermore, the images weren't being directly relied upon by the team leading many images to be built in the `si/merge-queue` pipeline that took at least as long as building our primary artifacts (and often longer). The approach taken here uses base images from Google's [Distroless] project which can be thought more of a way to statically build in the *runtime* requirements for a service. In our case, this image provides nothing more than the basic libc/libgcc/ssl/certificate environmental requrements for a dynamically linked Rust binary to work as expected. The container images use Debian 13 as their upstream basis for Glibc, GCC libs, etc. and so are just as compatible as any debian-derived base. So, these container images will use/consume an already-built binary and overlay it onto the image. This makes the image build phase very fast and similar to our "binary artifact" artifacts (which essentially tar up the binary). [Distroless]: https://github.com/GoogleContainerTools/distroless References ---------- - https://github.com/grafana/tempo/blob/main/cmd/tempo/Dockerfile - https://labs.iximiuz.com/tutorials/gcr-distroless-container-images - https://github.com/GoogleContainerTools/distroless - https://youtu.be/lviLZFciDv4?si=o-NWKb5dwgg1nsI- Signed-off-by: Fletcher Nichol --- bin/edda/BUCK | 14 ++++++++++++++ bin/edda/Dockerfile | 11 +++++++++++ bin/forklift/BUCK | 16 +++++++++++++++- bin/forklift/Dockerfile | 11 +++++++++++ bin/luminork/BUCK | 14 ++++++++++++++ bin/luminork/Dockerfile | 11 +++++++++++ bin/pinga/BUCK | 14 ++++++++++++++ bin/pinga/Dockerfile | 11 +++++++++++ bin/rebaser/BUCK | 14 ++++++++++++++ bin/rebaser/Dockerfile | 11 +++++++++++ bin/sdf/BUCK | 16 +++++++++++++++- bin/sdf/Dockerfile | 11 +++++++++++ bin/veritech/BUCK | 14 ++++++++++++++ bin/veritech/Dockerfile | 11 +++++++++++ 14 files changed, 177 insertions(+), 2 deletions(-) create mode 100644 bin/edda/Dockerfile create mode 100644 bin/forklift/Dockerfile create mode 100644 bin/luminork/Dockerfile create mode 100644 bin/pinga/Dockerfile create mode 100644 bin/rebaser/Dockerfile create mode 100644 bin/sdf/Dockerfile create mode 100644 bin/veritech/Dockerfile diff --git a/bin/edda/BUCK b/bin/edda/BUCK index 16d32a63c8..e578a48436 100644 --- a/bin/edda/BUCK +++ b/bin/edda/BUCK @@ -1,5 +1,6 @@ load( "@prelude-si//:macros.bzl", + "container_image", "rust_binary", "rust_binary_artifact", ) @@ -24,3 +25,16 @@ rust_binary_artifact( name = "edda", binary = ":edda", ) + +container_image( + name = "edda", + build_args = { + # Source: https://gcr.io/distroless/cc-debian13:nonroot + # Copy `Digest` value for exact pinning + "IMAGE": "gcr.io/distroless/cc-debian13", + "DIGEST": "sha256:580333af04e2a47e2578007066678939d06ff9c5c6bcbed07f7d9bb46b90b9d4", + }, + srcs = { + ":edda": ".", + }, +) diff --git a/bin/edda/Dockerfile b/bin/edda/Dockerfile new file mode 100644 index 0000000000..fe051bd1ae --- /dev/null +++ b/bin/edda/Dockerfile @@ -0,0 +1,11 @@ +# syntax=docker/dockerfile:1 +# check=skip=InvalidDefaultArgInFrom + +ARG IMAGE +ARG DIGEST + +FROM ${IMAGE}@${DIGEST} + +COPY ./edda /usr/local/bin/edda + +ENTRYPOINT ["/usr/local/bin/edda"] diff --git a/bin/forklift/BUCK b/bin/forklift/BUCK index db5884a329..06039f6afb 100644 --- a/bin/forklift/BUCK +++ b/bin/forklift/BUCK @@ -1,5 +1,6 @@ load( "@prelude-si//:macros.bzl", + "container_image", "rust_binary", "rust_binary_artifact", ) @@ -22,5 +23,18 @@ rust_binary( rust_binary_artifact( name = "forklift", - binary = ":forklift" + binary = ":forklift", +) + +container_image( + name = "forklift", + build_args = { + # Source: https://gcr.io/distroless/cc-debian13:nonroot + # Copy `Digest` value for exact pinning + "IMAGE": "gcr.io/distroless/cc-debian13", + "DIGEST": "sha256:580333af04e2a47e2578007066678939d06ff9c5c6bcbed07f7d9bb46b90b9d4", + }, + srcs = { + ":forklift": ".", + }, ) diff --git a/bin/forklift/Dockerfile b/bin/forklift/Dockerfile new file mode 100644 index 0000000000..ad11aab2b4 --- /dev/null +++ b/bin/forklift/Dockerfile @@ -0,0 +1,11 @@ +# syntax=docker/dockerfile:1 +# check=skip=InvalidDefaultArgInFrom + +ARG IMAGE +ARG DIGEST + +FROM ${IMAGE}@${DIGEST} + +COPY ./forklift /usr/local/bin/forklift + +ENTRYPOINT ["/usr/local/bin/forklift"] diff --git a/bin/luminork/BUCK b/bin/luminork/BUCK index 31d86a36d2..6cae452e20 100644 --- a/bin/luminork/BUCK +++ b/bin/luminork/BUCK @@ -1,5 +1,6 @@ load( "@prelude-si//:macros.bzl", + "container_image", "rust_binary", "rust_binary_artifact", ) @@ -28,3 +29,16 @@ rust_binary_artifact( name = "luminork", binary = ":luminork" ) + +container_image( + name = "luminork", + build_args = { + # Source: https://gcr.io/distroless/cc-debian13:nonroot + # Copy `Digest` value for exact pinning + "IMAGE": "gcr.io/distroless/cc-debian13", + "DIGEST": "sha256:580333af04e2a47e2578007066678939d06ff9c5c6bcbed07f7d9bb46b90b9d4", + }, + srcs = { + ":luminork": ".", + }, +) diff --git a/bin/luminork/Dockerfile b/bin/luminork/Dockerfile new file mode 100644 index 0000000000..7aa3cd3d2f --- /dev/null +++ b/bin/luminork/Dockerfile @@ -0,0 +1,11 @@ +# syntax=docker/dockerfile:1 +# check=skip=InvalidDefaultArgInFrom + +ARG IMAGE +ARG DIGEST + +FROM ${IMAGE}@${DIGEST} + +COPY ./luminork /usr/local/bin/luminork + +ENTRYPOINT ["/usr/local/bin/luminork"] diff --git a/bin/pinga/BUCK b/bin/pinga/BUCK index 83ee74d31b..de249709d6 100644 --- a/bin/pinga/BUCK +++ b/bin/pinga/BUCK @@ -1,5 +1,6 @@ load( "@prelude-si//:macros.bzl", + "container_image", "rust_binary", "rust_binary_artifact", ) @@ -25,3 +26,16 @@ rust_binary_artifact( name = "pinga", binary = ":pinga" ) + +container_image( + name = "pinga", + build_args = { + # Source: https://gcr.io/distroless/cc-debian13:nonroot + # Copy `Digest` value for exact pinning + "IMAGE": "gcr.io/distroless/cc-debian13", + "DIGEST": "sha256:580333af04e2a47e2578007066678939d06ff9c5c6bcbed07f7d9bb46b90b9d4", + }, + srcs = { + ":pinga": ".", + }, +) diff --git a/bin/pinga/Dockerfile b/bin/pinga/Dockerfile new file mode 100644 index 0000000000..ce20c53c35 --- /dev/null +++ b/bin/pinga/Dockerfile @@ -0,0 +1,11 @@ +# syntax=docker/dockerfile:1 +# check=skip=InvalidDefaultArgInFrom + +ARG IMAGE +ARG DIGEST + +FROM ${IMAGE}@${DIGEST} + +COPY ./pinga /usr/local/bin/pinga + +ENTRYPOINT ["/usr/local/bin/pinga"] diff --git a/bin/rebaser/BUCK b/bin/rebaser/BUCK index cf3d21c8fd..71fef666b2 100644 --- a/bin/rebaser/BUCK +++ b/bin/rebaser/BUCK @@ -1,5 +1,6 @@ load( "@prelude-si//:macros.bzl", + "container_image", "rust_binary", "rust_binary_artifact", ) @@ -25,3 +26,16 @@ rust_binary_artifact( name = "rebaser", binary = ":rebaser" ) + +container_image( + name = "rebaser", + build_args = { + # Source: https://gcr.io/distroless/cc-debian13:nonroot + # Copy `Digest` value for exact pinning + "IMAGE": "gcr.io/distroless/cc-debian13", + "DIGEST": "sha256:580333af04e2a47e2578007066678939d06ff9c5c6bcbed07f7d9bb46b90b9d4", + }, + srcs = { + ":rebaser": ".", + }, +) diff --git a/bin/rebaser/Dockerfile b/bin/rebaser/Dockerfile new file mode 100644 index 0000000000..717bf4569a --- /dev/null +++ b/bin/rebaser/Dockerfile @@ -0,0 +1,11 @@ +# syntax=docker/dockerfile:1 +# check=skip=InvalidDefaultArgInFrom + +ARG IMAGE +ARG DIGEST + +FROM ${IMAGE}@${DIGEST} + +COPY ./rebaser /usr/local/bin/rebaser + +ENTRYPOINT ["/usr/local/bin/rebaser"] diff --git a/bin/sdf/BUCK b/bin/sdf/BUCK index d1eb88bde2..73c5f83890 100644 --- a/bin/sdf/BUCK +++ b/bin/sdf/BUCK @@ -1,5 +1,6 @@ load( "@prelude-si//:macros.bzl", + "container_image", "rust_binary", "rust_binary_artifact", ) @@ -26,5 +27,18 @@ rust_binary( rust_binary_artifact( name = "sdf", - binary = ":sdf" + binary = ":sdf", +) + +container_image( + name = "sdf", + build_args = { + # Source: https://gcr.io/distroless/cc-debian13:nonroot + # Copy `Digest` value for exact pinning + "IMAGE": "gcr.io/distroless/cc-debian13", + "DIGEST": "sha256:580333af04e2a47e2578007066678939d06ff9c5c6bcbed07f7d9bb46b90b9d4", + }, + srcs = { + ":sdf": ".", + }, ) diff --git a/bin/sdf/Dockerfile b/bin/sdf/Dockerfile new file mode 100644 index 0000000000..366afcd248 --- /dev/null +++ b/bin/sdf/Dockerfile @@ -0,0 +1,11 @@ +# syntax=docker/dockerfile:1 +# check=skip=InvalidDefaultArgInFrom + +ARG IMAGE +ARG DIGEST + +FROM ${IMAGE}@${DIGEST} + +COPY ./sdf /usr/local/bin/sdf + +ENTRYPOINT ["/usr/local/bin/sdf"] diff --git a/bin/veritech/BUCK b/bin/veritech/BUCK index 906017012c..4a5dd9474d 100644 --- a/bin/veritech/BUCK +++ b/bin/veritech/BUCK @@ -1,5 +1,6 @@ load( "@prelude-si//:macros.bzl", + "container_image", "rust_binary", "rust_binary_artifact", ) @@ -28,3 +29,16 @@ rust_binary_artifact( name = "veritech", binary = ":veritech", ) + +container_image( + name = "veritech", + build_args = { + # Source: https://gcr.io/distroless/cc-debian13:nonroot + # Copy `Digest` value for exact pinning + "IMAGE": "gcr.io/distroless/cc-debian13", + "DIGEST": "sha256:580333af04e2a47e2578007066678939d06ff9c5c6bcbed07f7d9bb46b90b9d4", + }, + srcs = { + ":veritech": ".", + }, +) diff --git a/bin/veritech/Dockerfile b/bin/veritech/Dockerfile new file mode 100644 index 0000000000..fec9739f2c --- /dev/null +++ b/bin/veritech/Dockerfile @@ -0,0 +1,11 @@ +# syntax=docker/dockerfile:1 +# check=skip=InvalidDefaultArgInFrom + +ARG IMAGE +ARG DIGEST + +FROM ${IMAGE}@${DIGEST} + +COPY ./veritech /usr/local/bin/veritech + +ENTRYPOINT ["/usr/local/bin/veritech"]