FROM archlinux:latest # Metadata LABEL maintainer="marvin" LABEL description="Turnstone agent server, built as a boco container-VM" # Build-time arguments for UID/GID mapping ARG USER_ID=1000 ARG GROUP_ID=1000 # Set environment variables ENV HOME=/home/marvin # Install system dependencies via pacman RUN pacman -Syu --noconfirm && pacman -S --noconfirm --needed \ bash \ ca-certificates \ curl \ jq \ git \ github-cli \ tea \ helix \ nushell \ rust \ rust-analyzer \ rustfmt \ go \ podman \ base-devel \ openssl \ tar \ gzip \ openssh \ sudo \ python \ uv \ && pacman -Sc --noconfirm # Create the 'marvin' user and set up home directory with provided UID/GID RUN groupadd -g ${GROUP_ID} marvin || true && \ useradd -m -u ${USER_ID} -g marvin -s /bin/bash marvin && \ mkdir -p /home/marvin/.local/bin /home/marvin/work && \ install -d -o ${USER_ID} -g ${GROUP_ID} -m 750 /home/marvin/.config && \ chown -R marvin:marvin /home/marvin && \ echo "marvin ALL=(ALL) NOPASSWD:ALL" >> /etc/sudoers # Rootless podman subuid/subgid mapping (deterministic single entry — # duplicates make podman request overlapping uid_map ranges, which the # kernel rejects with EINVAL) RUN printf "marvin:100000:65536\n" > /etc/subuid && \ printf "marvin:100000:65536\n" > /etc/subgid # NOTE: don't bake /etc/hostname or /etc/hosts here — podman regenerates # both when boco creates the build container, so they never reach the # qcow2. The entrypoint sets the hostname live; node identity comes from # TURNSTONE_NODE_ID. # SSH access for marvin (pubkey generated by scripts/build.sh) COPY configs/ssh/authorized_keys /tmp/authorized_keys RUN install -o ${USER_ID} -g ${GROUP_ID} -m 700 -d /home/marvin/.ssh && \ install -o ${USER_ID} -g ${GROUP_ID} -m 600 /tmp/authorized_keys \ /home/marvin/.ssh/authorized_keys && \ rm /tmp/authorized_keys # Turnstone in a dedicated venv (Arch python is externally managed) RUN uv venv /opt/turnstone --python /usr/bin/python && \ uv pip install --python /opt/turnstone/bin/python turnstone && \ for f in /opt/turnstone/bin/turnstone*; do ln -s "$f" /usr/local/bin/; done # VM entrypoint (root: starts sshd, fixes share ownership, drops to marvin) COPY start-turnstone.sh /usr/local/bin/start-turnstone.sh RUN chmod 755 /usr/local/bin/start-turnstone.sh # Optional: paru + openscad from AUR (slow builds) # RUN git clone https://aur.archlinux.org/paru.git && \ # cd paru && makepkg -si --noconfirm && cd .. && rm -rf paru && \ # paru --removemake --cleanafter --aur -S openscad-git WORKDIR /home/marvin CMD ["/usr/local/bin/start-turnstone.sh"]