# Keep the Python version in sync with the production Dockerfile FROM python:3.15-slim-trixie ARG USERNAME=dev ARG USER_UID=1000 ARG USER_GID=$USER_UID # git + openssh-client: git over the host's forwarded SSH agent # gcc, libc-dev, libpq-dev: build psycopg2 from requirements.txt # postgresql-client, wait-for-it: scripts/db-setup.sh, scripts/psql.sh # curl, ca-certificates: Claude Code installer # vim: personal preferences RUN apt-get -y update && \ apt-get install --no-install-recommends -y \ git openssh-client make curl ca-certificates sudo \ gcc libc-dev libpq-dev \ postgresql-client wait-for-it \ vim && \ apt-get clean && rm -rf /var/lib/apt/lists/* RUN groupadd --gid $USER_GID $USERNAME && \ useradd --uid $USER_UID --gid $USER_GID -m -s /bin/bash $USERNAME && \ echo "$USERNAME ALL=(root) NOPASSWD:ALL" > /etc/sudoers.d/$USERNAME && \ chmod 0440 /etc/sudoers.d/$USERNAME # Project venv, owned by the dev user so pip works without sudo ENV VIRTUAL_ENV=/opt/venv RUN python -m venv $VIRTUAL_ENV && chown -R $USERNAME:$USERNAME $VIRTUAL_ENV ENV PATH="$VIRTUAL_ENV/bin:$PATH" USER $USERNAME # Claude Code (native installer, lands in ~/.local). The home dir is a volume # (see devcontainer.json); Claude then updates itself inside that volume. RUN curl -fsSL https://claude.ai/install.sh | bash ENV PATH="/home/$USERNAME/.local/bin:$PATH"