Arch image with turnstone (venv), dev toolkit, rootless podman; boots via boco (virtiofs shares, direct UID mapping for nested virtiofs). sshd ops channel + turnstone-server as guest marvin; state (SQLite db, config, work) on host shares; LLM via the TensorX OpenAI-compatible gateway (https://api.tensorx.ai/v1), reachable from the guest through both slirp layers with no relay.
77 lines
2.4 KiB
Docker
77 lines
2.4 KiB
Docker
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
|
|
|
|
# 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"]
|