Files
Quince ec780b2e73 Add prod deployment for the agent fleet (docker-compose.prod.yml)
- docker-compose.prod.yml + .env.prod.example: one container per agent, Quince
  first; deployed under /opt/gu_agents and wired into the server's start/stop.sh.
- Route API + git via host-gateway (containers can't hairpin the host's public IP).
- Dockerfile: drop the base image's uid-1000 user before creating quince.
- entrypoint: pip install --break-system-packages (Debian bookworm PEP 668).

Verified on prod: image builds, API reachable (200), PyPI egress ok, gutask
installs and runs, git clone from ramanujan works via host-gateway.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-10 10:42:46 +02:00

45 lines
2.0 KiB
Docker

# Quince — a scheduled, headless Claude Code agent for Glitch University.
# The image carries only tools. Everything that *is* Quince lives on the
# mounted volume at /home/quince, so the container stays disposable.
FROM node:22-bookworm-slim
# System tools: python (for gutasktool), git + openssh (for ramanujan),
# ca-certificates (HTTPS to the API), tzdata (for local-time scheduling),
# procps (ps/sleep niceties), curl.
RUN apt-get update && apt-get install -y --no-install-recommends \
python3 python3-pip python3-venv \
git openssh-client ca-certificates tzdata procps curl \
&& rm -rf /var/lib/apt/lists/*
# Claude Code CLI.
RUN npm install -g @anthropic-ai/claude-code
# Non-root user. Claude Code refuses --dangerously-skip-permissions as root,
# and we want the volume owned by a stable uid the agent can write to.
ARG QUINCE_UID=1000
# The node base image already has a user at uid 1000; drop it, then create quince.
RUN existing="$(getent passwd ${QUINCE_UID} | cut -d: -f1)"; \
if [ -n "$existing" ] && [ "$existing" != "quince" ]; then userdel -r "$existing" 2>/dev/null || true; fi; \
useradd --create-home --uid ${QUINCE_UID} --shell /bin/bash quince
# Entrypoint (scheduler loop) + wake script (one awakening).
COPY entrypoint.sh /usr/local/bin/entrypoint.sh
COPY wake.sh /usr/local/bin/wake.sh
RUN chmod +x /usr/local/bin/entrypoint.sh /usr/local/bin/wake.sh
# Baked identity. This is the canonical Quince — CLAUDE.md, GOALS.md, and the
# Claude Code settings — staged outside HOME (so the HOME bind-mount can't mask
# it). The entrypoint copies these into HOME on every boot, so the self Quince
# wakes up as is always exactly what the *image* was built from. Change the self
# by editing deploy/identity/ in the repo and rebuilding.
COPY identity/ /opt/quince/identity/
USER quince
ENV HOME=/home/quince
# ~/.local/bin holds the `gutask` console script after pip install --user -e.
ENV PATH=/home/quince/.local/bin:$PATH
WORKDIR /home/quince
ENTRYPOINT ["/usr/local/bin/entrypoint.sh"]