Binaries built on Ubuntu 22.04 require GLIBC_2.34 and GLIBCXX_3.4.30 and will not
start on Ubuntu 20.04 -- which is four of our five seeds, and an unknown share of
users. The binary the fleet actually runs today needs only GLIBC_2.29, so it was
built somewhere older; seed 176 has since been upgraded to 22.04 and now produces
binaries it is the only seed able to run.
--linux-compat and Dockerfile.compat already solved this (6d56ad854) but were
undocumented outside the build script and pinned to one base image. Parameterise
the base via ARG BASE_IMAGE (default unchanged, so --linux-compat behaves exactly
as before) and document the whole path.
doc/build-containers.md is written to be executed by a person or an agent starting
from a machine with nothing installed: why the glibc direction matters, with the
measured numbers; what already exists in the repo so nobody writes a second build
system; prerequisites and honest cost (~15GB, 4GB RAM, 1-2h per base because
depends/ builds boost, BDB, wolfssl and rust from source); one-target and
multi-target recipes; which base to pick and why 20.04 is the recommended floor
while 18.04 needs verifying (GCC 7 against -std=c++17); a mandatory verification
step with the exact objdump/readelf commands and the expected ceilings; and the
traps.
The traps are the part worth having written down: ETXTBSY when installing over a
running daemon (cp fails even after the process exits -- stage and rename, then
sha256-verify before starting); never touching configure.ac in a configured tree,
because the mtime alone triggers a reconfigure that dies on libdb_cxx; never
blind-touching a path that may not exist, which silently creates stray empty files;
RandomX needing ARCH=default or it emits AVX-512 that SIGILLs the fleet; build-win.sh
silently discarding every argument; and macOS being uncontainerisable because
depends/ has no darwin cross path at all.
Also records that full static linking is NOT the answer here: the daemon resolves
node1..node5.dragonx.is via getaddrinfo, and static glibc pushes that through NSS,
which dlopens libnss_dns at runtime and reintroduces the dependency it was meant to
remove.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
36 lines
1.4 KiB
Docker
36 lines
1.4 KiB
Docker
# Base image is parameterised so one Dockerfile can produce binaries for several
|
|
# glibc floors: docker build --build-arg BASE_IMAGE=ubuntu:18.04 ...
|
|
# The default is unchanged, so `./build.sh --linux-compat` behaves exactly as before.
|
|
ARG BASE_IMAGE=ubuntu:20.04
|
|
FROM ${BASE_IMAGE}
|
|
|
|
ENV DEBIAN_FRONTEND=noninteractive
|
|
|
|
RUN apt-get update && apt-get install -y \
|
|
build-essential pkg-config libc6-dev m4 g++-multilib autoconf libtool \
|
|
ncurses-dev unzip python3 zlib1g-dev wget bsdmainutils automake cmake \
|
|
libcurl4-openssl-dev curl git binutils \
|
|
&& apt-get clean && rm -rf /var/lib/apt/lists/*
|
|
|
|
WORKDIR /build
|
|
COPY . /build/
|
|
|
|
# Clean host-built depends and src artifacts to force full rebuild inside container
|
|
RUN rm -rf /build/depends/built /build/depends/work \
|
|
/build/depends/x86_64-unknown-linux-gnu \
|
|
/build/depends/x86_64-w64-mingw32 \
|
|
/build/src/RandomX/build \
|
|
&& find /build/src -name '*.o' -o -name '*.a' -o -name '*.la' -o -name '*.lo' \
|
|
-o -name '*.lai' | xargs rm -f \
|
|
&& rm -rf /build/src/univalue/.libs /build/src/univalue/.deps \
|
|
&& rm -rf /build/src/.libs /build/src/.deps \
|
|
&& rm -rf /build/src/cc/*.o /build/src/cc/*.a \
|
|
&& rm -f /build/config.status /build/config.log
|
|
|
|
RUN cd /build && ./util/build.sh --disable-tests -j$(nproc)
|
|
|
|
# Strip binaries inside the container so extracted files are already small
|
|
RUN strip /build/src/dragonxd /build/src/dragonx-cli /build/src/dragonx-tx
|
|
|
|
CMD ["/bin/bash"]
|