77# the Business Source License, use of this software will be governed
88# by the Apache License, Version 2.0.
99
10- # Build a cross-compiling toolchain that targets the oldest version of Linux
11- # that we support.
10+ # Stage 1: Build a minimum CI Builder image that we can use for the initial
11+ # steps like `mkpipeline` and `Build`, as well as any tests that are self
12+ # contained and use other Docker images.
13+ FROM ubuntu:noble-20241015 AS ci-builder-min
1214
15+ WORKDIR /workdir
16+
17+ ARG ARCH_GCC
18+ ARG ARCH_GO
19+
20+ # Environment variables that should be set for the entire build container.
21+
22+ # Ensure any Rust binaries that crash print a backtrace.
23+ ENV RUST_BACKTRACE=1
24+ # Ensure that all python output is unbuffered, otherwise it is not
25+ # logged properly in Buildkite.
26+ ENV PYTHONUNBUFFERED=1
27+ # Set a environment variable that tools can check to see if they're in the
28+ # builder or not.
29+ ENV MZ_DEV_CI_BUILDER=1
30+
31+ # Faster uncompression
32+ ARG XZ_OPT=-T0
33+
34+ # Absolute minimum set of dependencies needed for a CI job.
35+ #
36+ # Please take care with what gets added here. The goal of this initial layer is to be as small as
37+ # possible since it's used for the `mkpipeline` and `Build` CI jobs, which block __all other__
38+ # jobs.
39+ RUN apt-get update --fix-missing && TZ=UTC DEBIAN_FRONTEND=noninteractive apt-get install -y --no-install-recommends \
40+ ca-certificates \
41+ curl \
42+ docker.io \
43+ gdb \
44+ git \
45+ gnupg2 \
46+ libxml2 \
47+ python3 \
48+ && rm -rf /var/lib/apt/lists/*
49+
50+ # Install Python dependencies. These are necessary to run some of our base tooling.
51+ COPY requirements.txt /workdir/
52+ RUN curl -LsSf https://astral.sh/uv/0.4.25/install.sh | UV_INSTALL_DIR=/usr/local UV_UNMANAGED_INSTALL=1 sh \
53+ && uv pip install --system --break-system-packages -r /workdir/requirements.txt && rm /workdir/requirements*.txt
54+
55+ # Install extra tools not available in apt repositories.
56+
57+ COPY rust.asc .
58+ RUN gpg --import rust.asc \
59+ && rm rust.asc \
60+ && echo "trusted-key 85AB96E6FA1BE5FE" >> ~/.gnupg/gpg.conf
61+
62+ ARG BAZEL_VERSION
63+ ARG RUST_DATE
64+ ARG RUST_VERSION
65+
66+ RUN \
67+ # 1. autouseradd
68+ #
69+ # Ensures that the UID used when running the container has a proper entry in
70+ # `/etc/passwd`, and writable home directory.
71+ curl -fsSL https://github.com/benesch/autouseradd/releases/download/1.3.0/autouseradd-1.3.0-$ARCH_GO.tar.gz \
72+ | tar xz -C / --strip-components 1 \
73+ # 2. Bazel
74+ #
75+ # We primarily build Materialize via Bazel in CI, and Bazel pulls in its own dependencies.
76+ && arch_bazel=$(echo "$ARCH_GCC" | sed -e "s/aarch64/arm64/" -e "s/amd64/x86_64/" ) bazel_version=$(echo "$BAZEL_VERSION" ) \
77+ && curl -fsSL -o /usr/local/bin/bazel https://github.com/bazelbuild/bazel/releases/download/$bazel_version/bazel-$bazel_version-linux-$arch_bazel \
78+ && if [ "$arch_bazel" = arm64 ]; then echo 'fac4b954e0501c2be8b9653a550b443eb85284e568d08b102977e2bf587b09d7 /usr/local/bin/bazel' | sha256sum --check; fi \
79+ && if [ "$arch_bazel" = x86_64 ]; then echo '48ea0ff9d397a48add6369c261c5a4431fe6d5d5348cfb81411782fb80c388d3 /usr/local/bin/bazel' | sha256sum --check; fi \
80+ && chmod +x /usr/local/bin/bazel \
81+ # 3. Docker
82+ #
83+ # If you upgrade Docker (Compose) version here, also update it in misc/python/cli/mzcompose.py.
84+ && mkdir -p /usr/local/lib/docker/cli-plugins \
85+ && curl -fsSL https://github.com/docker/compose/releases/download/v2.15.1/docker-compose-linux-$ARCH_GCC > /usr/local/lib/docker/cli-plugins/docker-compose \
86+ && chmod +x /usr/local/lib/docker/cli-plugins/docker-compose \
87+ && curl -fsSL https://github.com/christian-korneck/docker-pushrm/releases/download/v1.9.0/docker-pushrm_linux_$ARCH_GO > /usr/local/lib/docker/cli-plugins/docker-pushrm \
88+ && chmod +x /usr/local/lib/docker/cli-plugins/docker-pushrm \
89+ # 4. Cargo
90+ #
91+ # Some parts of our stack use 'cargo' to read metadata, so we install just that. Importantly we
92+ # do not install 'rustc' or any of the other tools, this keeps the Docker image small.
93+ && mkdir rust \
94+ && curl -fsSL https://static.rust-lang.org/dist$RUST_DATE/rust-$RUST_VERSION-$ARCH_GCC-unknown-linux-gnu.tar.gz > rust.tar.gz \
95+ && curl -fsSL https://static.rust-lang.org/dist$RUST_DATE/rust-$RUST_VERSION-$ARCH_GCC-unknown-linux-gnu.tar.gz.asc > rust.asc \
96+ && gpg --verify rust.asc rust.tar.gz \
97+ && tar -xzf rust.tar.gz -C rust --strip-components=1 \
98+ && rust/install.sh --components=cargo \
99+ && rm -rf rust.asc rust.tar.gz rust
100+
101+ # Make the image as small as possible.
102+ RUN find /workdir /root -mindepth 1 -maxdepth 1 -exec rm -rf {} +
103+
104+ # Remove Ubuntu user causing UID collisions.
105+ # https://bugs.launchpad.net/cloud-images/+bug/2005129
106+ RUN userdel -r ubuntu
107+
108+ ENTRYPOINT ["autouseradd" , "--user" , "materialize" ]
109+
110+ # Stage 2. Build a cross-compiling toolchain that targets the oldest version of
111+ # Linux that we support.
112+ #
113+ # TODO(parkmycar): This shouldn't be necessary anymore with Bazel.
13114FROM ubuntu:noble-20241015 as crosstool
115+
14116ARG ARCH_GCC
15117ARG ARCH_GO
16118
@@ -68,10 +170,10 @@ RUN DEFCONFIG=crosstool-$ARCH_GCC.defconfig ct-ng defconfig \
68170 && rm crosstool-$ARCH_GCC.defconfig \
69171 && ct-ng build
70172
71- # Import the cross-compiling toolchain into a fresh image, omitting the
72- # dependencies that we needed to actually build the toolchain.
173+ # Stage 3: Build a full CI Builder image that imports the cross-compiling
174+ # toolchain and can be used for any CI job.
175+ FROM ci-builder-min as ci-builder-full
73176
74- FROM ubuntu:noble-20241015
75177ARG ARCH_GCC
76178ARG ARCH_GO
77179
@@ -135,9 +237,7 @@ RUN gpg --dearmor < nodesource.asc > /etc/apt/keyrings/nodesource.gpg \
135237 && apt-get update \
136238 && apt-get install -y --no-install-recommends nodejs
137239
138- RUN curl -fsSL https://github.com/benesch/autouseradd/releases/download/1.3.0/autouseradd-1.3.0-$ARCH_GO.tar.gz \
139- | tar xz -C / --strip-components 1 \
140- && curl -fsSL https://github.com/koalaman/shellcheck/releases/download/v0.8.0/shellcheck-v0.8.0.linux.$ARCH_GCC.tar.xz > shellcheck.tar.xz \
240+ RUN curl -fsSL https://github.com/koalaman/shellcheck/releases/download/v0.8.0/shellcheck-v0.8.0.linux.$ARCH_GCC.tar.xz > shellcheck.tar.xz \
141241 && tar -xJf shellcheck.tar.xz -C /usr/local/bin --strip-components 1 shellcheck-v0.8.0/shellcheck \
142242 && rm shellcheck.tar.xz \
143243 && curl -fsSL https://github.com/bufbuild/buf/releases/download/v1.18.0/buf-Linux-$ARCH_GCC.tar.gz > buf.tar.gz \
@@ -148,12 +248,6 @@ RUN curl -fsSL https://github.com/benesch/autouseradd/releases/download/1.3.0/au
148248 && tar -xf kail.tar.gz -C /usr/local/bin kail \
149249 && rm kail.tar.gz \
150250 && chmod +x /usr/local/bin/kail \
151- && mkdir -p /usr/local/lib/docker/cli-plugins \
152- # If you upgrade Docker (Compose) version here, also update it in misc/python/cli/mzcompose.py \
153- && curl -fsSL https://github.com/docker/compose/releases/download/v2.15.1/docker-compose-linux-$ARCH_GCC > /usr/local/lib/docker/cli-plugins/docker-compose \
154- && chmod +x /usr/local/lib/docker/cli-plugins/docker-compose \
155- && curl -fsSL https://github.com/christian-korneck/docker-pushrm/releases/download/v1.9.0/docker-pushrm_linux_$ARCH_GO > /usr/local/lib/docker/cli-plugins/docker-pushrm \
156- && chmod +x /usr/local/lib/docker/cli-plugins/docker-pushrm \
157251 && curl -fsSL https://github.com/parca-dev/parca-debuginfo/releases/download/v0.11.0/parca-debuginfo_0.11.0_Linux_$(echo "$ARCH_GCC" | sed "s/aarch64/arm64/" ).tar.gz \
158252 | tar xz -C /usr/local/bin parca-debuginfo
159253
@@ -212,8 +306,6 @@ RUN mkdir rust \
212306RUN ln -s /usr/bin/lld /opt/x-tools/$ARCH_GCC-unknown-linux-gnu/bin/$ARCH_GCC-unknown-linux-gnu-ld.lld \
213307 && ln -s /usr/bin/lld /opt/x-tools/$ARCH_GCC-unknown-linux-gnu/bin/$ARCH_GCC-unknown-linux-gnu-lld
214308
215- RUN curl -LsSf https://astral.sh/uv/0.4.25/install.sh | UV_INSTALL_DIR=/usr/local UV_UNMANAGED_INSTALL=1 sh
216-
217309# Shims for sanitizers
218310COPY sanshim/$ARCH_GCC /sanshim
219311
@@ -223,13 +315,6 @@ COPY sanshim/$ARCH_GCC /sanshim
223315COPY pyright-version.sh /workdir/
224316RUN npx pyright@$(sh /workdir/pyright-version.sh) --help
225317
226- # Install Python dependencies. These are so quick to install and change
227- # frequently enough that it makes sense to install them last.
228-
229- COPY requirements.txt /workdir/
230-
231- RUN uv pip install --system --break-system-packages -r /workdir/requirements.txt && rm /workdir/requirements*.txt
232-
233318# Install APT repo generator.
234319
235320RUN curl -fsSL https://github.com/deb-s3/deb-s3/releases/download/0.11.3/deb-s3-0.11.3.gem > deb-s3.gem \
@@ -258,21 +343,7 @@ RUN if [ $ARCH_GCC = x86_64 ]; then \
258343 && rm hugo.tar.gz; \
259344 fi
260345
261- # Install Bazel.
262- #
263- # TODO(parkmycar): Run Bazel in a Docker image that does not have access to clang/gcc or any other tools.
264-
265- ARG BAZEL_VERSION
266-
267- # Download the bazel binary from the official GitHub releases since the apt repositories do not
268- # contain arm64 releases.
269- RUN arch_bazel=$(echo "$ARCH_GCC" | sed -e "s/aarch64/arm64/" -e "s/amd64/x86_64/" ) bazel_version=$(echo "$BAZEL_VERSION" ) \
270- && curl -fsSL -o /usr/local/bin/bazel https://github.com/bazelbuild/bazel/releases/download/$bazel_version/bazel-$bazel_version-linux-$arch_bazel \
271- && if [ "$arch_bazel" = arm64 ]; then echo 'fac4b954e0501c2be8b9653a550b443eb85284e568d08b102977e2bf587b09d7 /usr/local/bin/bazel' | sha256sum --check; fi \
272- && if [ "$arch_bazel" = x86_64 ]; then echo '48ea0ff9d397a48add6369c261c5a4431fe6d5d5348cfb81411782fb80c388d3 /usr/local/bin/bazel' | sha256sum --check; fi \
273- && chmod +x /usr/local/bin/bazel
274-
275- # Install KinD, kubectl, helm, helm-docs & terraform
346+ # Install KinD, kubectl, helm & helm-docs
276347
277348RUN curl -fsSL https://kind.sigs.k8s.io/dl/v0.14.0/kind-linux-$ARCH_GO > /usr/local/bin/kind \
278349 && chmod +x /usr/local/bin/kind \
@@ -340,28 +411,11 @@ ENV CARGO_TARGET_DIR=/mnt/build
340411ENV CARGO_INCREMENTAL=0
341412ENV HELM_PLUGINS=/usr/local/share/helm/plugins
342413
343- # Set a environment variable that tools can check to see if they're in the
344- # builder or not.
345-
346- ENV MZ_DEV_CI_BUILDER=1
347-
348414# Set up for a persistent volume to hold Cargo metadata, so that crate metadata
349415# does not need to be refetched on every compile.
350-
351416ENV CARGO_HOME=/cargo
352417RUN mkdir /cargo && chmod 777 /cargo
353418VOLUME /cargo
354419
355- # Ensure any Rust binaries that crash print a backtrace.
356- ENV RUST_BACKTRACE=1
357-
358420# Make the image as small as possible.
359421RUN find /workdir /root -mindepth 1 -maxdepth 1 -exec rm -rf {} +
360-
361- # remove Ubuntu user causing UID collisions
362- # https://bugs.launchpad.net/cloud-images/+bug/2005129
363- RUN userdel -r ubuntu
364-
365- # Ensure that all python output is unbuffered, otherwise it is not
366- # logged properly in Buildkite
367- ENV PYTHONUNBUFFERED=1
0 commit comments