Files
codam-webserver-team/docker/Dockerfile
T
2026-09-07 00:45:35 +02:00

92 lines
3.6 KiB
Docker

# Development environment for webserv.
#
# Target platform is Linux, because that is what the Codam VMs run and what the
# official testers are built for. The base is Ubuntu 22.04, the same release
# those VMs run, so this image is that environment rather than something close
# to it. A newer base would be the permissive side of the difference: its glibc
# accepts everything the older one does and more, so code that cannot run at
# school would still build clean here. On 24.04 a plain std::strtoul compiles
# into a call to __isoc23_strtoul, a GLIBC_2.38 symbol that 22.04 does not have,
# at every -std= and not only at C++23.
#
# 22.04 ships neither compiler this project needs, so two repositories are
# added: ubuntu-toolchain-r/test for g++ 14, apt.llvm.org for clang 18. Both
# publish builds made for 22.04, which is what keeps the produced binary
# runnable there.
#
# libc++ is installed alongside libstdc++ for one specific reason: clang 18
# reports __cpp_concepts as 201907, and libstdc++ gates <expected> on 202002L,
# so clang + libstdc++ compiles "#include <expected>" into nothing at all. The
# control build with clang — a second opinion on warnings, and the sanitizers —
# would die on the first function returning Result<T>. "make check-clang" passes
# -stdlib=libc++ for exactly this.
FROM ubuntu:22.04
ENV DEBIAN_FRONTEND=noninteractive
RUN apt-get update && apt-get install -y --no-install-recommends \
ca-certificates \
gnupg \
wget \
lsb-release \
software-properties-common \
&& add-apt-repository -y ppa:ubuntu-toolchain-r/test \
&& wget -qO- https://apt.llvm.org/llvm-snapshot.gpg.key \
| gpg --dearmor -o /usr/share/keyrings/llvm-archive-keyring.gpg \
&& echo "deb [signed-by=/usr/share/keyrings/llvm-archive-keyring.gpg]" \
"http://apt.llvm.org/jammy/ llvm-toolchain-jammy-18 main" \
> /etc/apt/sources.list.d/llvm.list \
&& apt-get update
RUN apt-get install -y --no-install-recommends \
build-essential \
g++-14 \
clang-18 \
clang-tidy-18 \
clang-format-18 \
libc++-18-dev \
libc++abi-18-dev \
libclang-rt-18-dev \
gdb \
valgrind \
strace \
make \
git \
curl \
siege \
python3 \
python3-pip \
net-tools \
iproute2 \
procps \
less \
vim \
&& rm -rf /var/lib/apt/lists/*
# Make the versioned tools the defaults, so "c++", "g++", "clang++",
# "clang-tidy" and "clang-format" all point at something that understands C++23.
# Without the last two the Makefile would have to hardcode Ubuntu's versioned
# names, which are wrong everywhere else — Codam included.
RUN update-alternatives --install /usr/bin/g++ g++ /usr/bin/g++-14 100 \
&& update-alternatives --install /usr/bin/gcc gcc /usr/bin/gcc-14 100 \
&& update-alternatives --install /usr/bin/clang++ clang++ /usr/bin/clang++-18 100 \
&& update-alternatives --install /usr/bin/c++ c++ /usr/bin/g++-14 100 \
&& update-alternatives --install /usr/bin/clang-tidy clang-tidy \
/usr/bin/clang-tidy-18 100 \
&& update-alternatives --install /usr/bin/clang-format clang-format \
/usr/bin/clang-format-18 100
# Run as a normal user whose uid/gid match the host account, so files created
# inside the container (object files, uploads, test output) do not end up owned
# by root on the macOS side of the bind mount.
ARG UID=1000
ARG GID=1000
RUN if getent passwd ${UID} >/dev/null; then userdel -r "$(getent passwd ${UID} | cut -d: -f1)"; fi \
&& groupadd -g ${GID} dev 2>/dev/null || true \
&& useradd -m -u ${UID} -g ${GID} -s /bin/bash dev
USER dev
WORKDIR /webserv
CMD ["/bin/bash"]