Files
Max KainovandClaude Opus 4.8 77973364a7 Roll out in-region apt mirror to all arm64 CI docker images
The mirror override was only applied to a subset of images. Every other
arm64 CI image built directly `FROM ubuntu` still resolved through
`ports.ubuntu.com` and was subject to the same failure.

Add a generic `build_args` field to `Docker.Config` and pass the
in-region AWS mirror (`apt_archive` / `apt_ports_archive`, set literally in
`ci/defs/defs.py`) to the Ubuntu-based CI images on the command line.
`ci/praktika/docker.py` stays generic - it just forwards `build_args` and
knows nothing about apt or the region. Images that don't declare the args
ignore them.

Dockerfile defaults stay canonical so local builds are unchanged, and the
remaining direct-`ubuntu` arm64 images (`style-test`, `install-deb-test`,
`sqlancer-test`, `mysql_dotnet_client`, `postgresql-java-client`) get a
`ports`- and deb822-aware rewrite so the passed mirror reaches arm64.

Co-Authored-By: Claude Opus 4.8 (1M context) <[email protected]>
2026-07-17 13:33:50 +02:00

181 lines
7.4 KiB
Docker

# docker build -t clickhouse/fasttest .
FROM ubuntu:24.04
# ARG for quick switch to a given ubuntu mirror. Defaults stay canonical so local
# builds are unchanged; CI passes the in-region AWS mirror on the command line
# (see ci/praktika/docker.py). amd64 base images use archive.ubuntu.com, arm64
# uses ports.ubuntu.com, so rewrite both. On 24.04 the sources live in the deb822
# file /etc/apt/sources.list.d/ubuntu.sources, so rewrite every apt source file.
# The runners have no IPv6 egress, so force IPv4 to avoid hanging on IPv6 connect
# attempts (this is a CI-only image, never pulled by end users, so forcing IPv4
# here is safe). Also retry transient apt failures.
ARG apt_archive="http://archive.ubuntu.com"
ARG apt_ports_archive="http://ports.ubuntu.com"
RUN find /etc/apt -type f \( -name '*.list' -o -name '*.sources' \) -print0 | xargs -0 -r sed -i \
-e "s|http://archive.ubuntu.com|$apt_archive|g" \
-e "s|https://archive.ubuntu.com|$apt_archive|g" \
-e "s|http://ports.ubuntu.com|$apt_ports_archive|g" \
-e "s|https://ports.ubuntu.com|$apt_ports_archive|g" \
&& printf 'Acquire::ForceIPv4 "true";\nAcquire::Retries "5";\n' > /etc/apt/apt.conf.d/99-clickhouse-ci
ARG LLVM_APT_VERSION="1:21.1.5~"
ENV DEBIAN_FRONTEND=noninteractive LLVM_VERSION=21
# We need ca-certificates first to be able to update all repos. This is why it's run twice
RUN apt-get update \
&& apt-get install ca-certificates --yes --no-install-recommends --verbose-versions
RUN apt-get update \
&& apt-get install \
apt-transport-https \
apt-utils \
curl \
netcat-openbsd \
gnupg \
lsb-release \
wget \
git \
xxd \
time \
--yes --no-install-recommends --verbose-versions \
&& export LLVM_PUBKEY_HASH="5ffc7c9a9299ce774f81cada703e23ebba5bdfb0345b6c3b667b3ead7aa21c75ef62ccd74f7a8f2aa0cbe158d3068bbe" \
&& wget -nv -O /tmp/llvm-snapshot.gpg.key https://apt.llvm.org/llvm-snapshot.gpg.key \
&& echo "${LLVM_PUBKEY_HASH} /tmp/llvm-snapshot.gpg.key" | sha384sum -c \
&& apt-key add /tmp/llvm-snapshot.gpg.key \
&& export CODENAME="$(lsb_release --codename --short | tr 'A-Z' 'a-z')" \
&& echo "deb https://apt.llvm.org/${CODENAME}/ llvm-toolchain-${CODENAME}-${LLVM_VERSION} main" >> /etc/apt/sources.list.d/llvm.list \
&& apt-get update \
&& apt-get satisfy --yes --no-install-recommends "llvm-${LLVM_VERSION} (>= ${LLVM_APT_VERSION})" \
&& apt-get clean \
&& rm -rf /var/lib/apt/lists/* /var/cache/debconf /tmp/*
# Install cmake 3.20+ for Rust support
# Used https://askubuntu.com/a/1157132 as reference
RUN curl -s https://apt.kitware.com/keys/kitware-archive-latest.asc | gpg --dearmor - > /etc/apt/trusted.gpg.d/kitware.gpg && \
echo "deb [signed-by=/etc/apt/trusted.gpg.d/kitware.gpg] https://apt.kitware.com/ubuntu/ $(lsb_release -cs) main" >> /etc/apt/sources.list.d/kitware.list
# moreutils - provides ts fo FT
# expect, bzip2, less - requried by FT
# bsdmainutils - provides hexdump for FT
# nasm - nasm copiler for one of submodules, required from normal build
# yasm - asssembler for libhdfs3, required from normal build
RUN apt-get update \
&& apt-get install \
clang-${LLVM_VERSION} \
clang-tidy-${LLVM_VERSION} \
cmake \
libclang-${LLVM_VERSION}-dev \
libclang-rt-${LLVM_VERSION}-dev \
lld-${LLVM_VERSION} \
llvm-${LLVM_VERSION}-dev \
libmpfr6 \
lsof \
ninja-build \
python3 \
python3-pip \
zstd \
unzip \
moreutils \
less \
expect \
bsdmainutils \
pv \
jq \
bzip2 \
nasm \
yasm \
--yes --no-install-recommends \
&& apt-get clean \
&& rm -rf /var/lib/apt/lists/* /var/cache/debconf /tmp/*
# Rust toolchain and libraries
ENV RUSTUP_HOME=/rust/rustup
ENV CARGO_HOME=/rust/cargo
ENV PATH="/rust/cargo/bin:${PATH}"
ENV RUSTUP_VERSION=1.28.1
RUN ARCH=$(uname -m) && \
if [ "$ARCH" = "x86_64" ]; then \
RUSTUP_ARCH="x86_64-unknown-linux-gnu"; \
elif [ "$ARCH" = "aarch64" ]; then \
RUSTUP_ARCH="aarch64-unknown-linux-gnu"; \
else \
echo "Unsupported architecture: $ARCH"; exit 1; \
fi && \
curl -fsSL -o rustup-init "https://static.rust-lang.org/rustup/archive/${RUSTUP_VERSION}/${RUSTUP_ARCH}/rustup-init" && \
chmod +x rustup-init && \
./rustup-init -y && \
rm rustup-init && \
chmod 777 -R /rust && \
rustup toolchain install nightly-2026-03-22 --no-self-update && \
rustup default nightly-2026-03-22 && \
rustup toolchain remove stable && \
rustup component add rust-src && \
rustup target add x86_64-unknown-linux-gnu && \
rustup target add aarch64-unknown-linux-gnu && \
rustup target add x86_64-apple-darwin && \
rustup target add x86_64-unknown-freebsd && \
rustup target add aarch64-apple-darwin && \
rustup target add powerpc64le-unknown-linux-gnu && \
rustup target add x86_64-unknown-linux-musl && \
rustup target add aarch64-unknown-linux-musl && \
rustup target add riscv64gc-unknown-linux-gnu
# Note, libmpfr6 is also a requirement for gdb
COPY --from=clickhouse/cctools:859fb360308eb8ac47ad /opt/gdb /opt/gdb
# Give suid to gdb to grant it attach permissions
RUN chmod u+s /opt/gdb/bin/gdb
ENV PATH="/opt/gdb/bin:${PATH}"
# This symlink is required by gcc to find the lld linker
RUN ln -s /usr/bin/lld-${LLVM_VERSION} /usr/bin/ld.lld
# FIXME: workaround for "The imported target "merge-fdata" references the file" error
# https://salsa.debian.org/pkg-llvm-team/llvm-toolchain/-/commit/992e52c0b156a5ba9c6a8a54f8c4857ddd3d371d
RUN sed -i '/_IMPORT_CHECK_FILES_FOR_\(mlir-\|llvm-bolt\|merge-fdata\|MLIR\)/ {s|^|#|}' /usr/lib/llvm-${LLVM_VERSION}/lib/cmake/llvm/LLVMExports-*.cmake
ARG TARGETARCH
ARG SCCACHE_VERSION=v0.10.0
ENV SCCACHE_IGNORE_SERVER_IO_ERROR=1
# sccache requires a value for the region. So by default we use The Default Region
ENV SCCACHE_REGION=us-east-1
RUN arch=${TARGETARCH} \
&& case $arch in \
amd64) rarch=x86_64 ;; \
arm64) rarch=aarch64 ;; \
esac \
&& curl -Ls "https://github.com/mozilla/sccache/releases/download/$SCCACHE_VERSION/sccache-$SCCACHE_VERSION-$rarch-unknown-linux-musl.tar.gz" | \
tar xz -C /tmp \
&& mv "/tmp/sccache-$SCCACHE_VERSION-$rarch-unknown-linux-musl/sccache" /usr/bin \
&& rm "/tmp/sccache-$SCCACHE_VERSION-$rarch-unknown-linux-musl" -r
COPY requirements.txt /
RUN pip3 install --break-system-packages --no-cache-dir -r /requirements.txt
RUN curl "https://awscli.amazonaws.com/awscli-exe-linux-$(uname -m).zip" -o "awscliv2.zip" \
&& unzip -q awscliv2.zip \
&& ./aws/install \
&& rm -rf awscliv2.zip aws
# chmod 777 to make the container user independent
RUN mkdir -p /var/lib/clickhouse \
&& chmod 777 /var/lib/clickhouse
ENV TZ=Europe/Amsterdam
RUN ln -snf /usr/share/zoneinfo/$TZ /etc/localtime && echo $TZ > /etc/timezone
RUN (userdel -r ubuntu 2>/dev/null || true) && (groupdel ubuntu 2>/dev/null || true) \
&& groupadd --system --gid 1000 clickhouse \
&& useradd --system --gid 1000 --uid 1000 -m clickhouse \
&& mkdir -p /.cache/sccache && chmod 777 /.cache/sccache
# TODO move nfpm to docker that will do packaging
ARG TARGETARCH
ARG NFPM_VERSION=2.20.0
RUN arch=${TARGETARCH:-amd64} \
&& curl -Lo /tmp/nfpm.deb "https://github.com/goreleaser/nfpm/releases/download/v${NFPM_VERSION}/nfpm_${arch}.deb" \
&& dpkg -i /tmp/nfpm.deb \
&& rm /tmp/nfpm.deb
ENV PYTHONUNBUFFERED=1