# A box shaped like one you would actually be handed, not one shaped to make # the tests pass. # # Three details are load-bearing, and each of them hid a real bug: # # non-root user the old harness ran as root, where ~/.local/bin, sudo and # $HOME all behave differently. # bash login Ubuntu's own ~/.profile prepends ~/.local/bin ONLY if that # directory already exists when the shell starts. A session # opened before the install therefore does NOT have it, which # is precisely why `dotup` came back "command not found" on a # real machine and never once in CI. # curl but no git the cloud images ship curl; git arrives with chezmoi's # installer or not at all. # # Nothing else is pre-installed. Anything the tests need beyond this -- expect, # zsh -- is installed by the scenario that needs it, so a dependency can never # be silently satisfied by the image. ARG BASE=ubuntu:24.04 FROM ${BASE} ARG USER=ben ARG UID=1001 ENV DEBIAN_FRONTEND=noninteractive RUN apt-get update -qq \ && apt-get install -y -qq --no-install-recommends \ ca-certificates curl sudo locales tzdata \ && locale-gen en_US.UTF-8 >/dev/null 2>&1 \ && rm -rf /var/lib/apt/lists/* # `ubuntu` already owns 1000 in 24.04, so take the next id rather than fighting # it. Passwordless sudo matches a cloud image; the installer must never assume # it, but it must work when it is there. RUN useradd -m -u ${UID} -s /bin/bash ${USER} \ && printf '%s ALL=(ALL) NOPASSWD:ALL\n' "${USER}" > /etc/sudoers.d/90-${USER} \ && chmod 440 /etc/sudoers.d/90-${USER} ENV LANG=en_US.UTF-8 LC_ALL=en_US.UTF-8 USER ${USER} WORKDIR /home/${USER} CMD ["sleep", "infinity"]