# vibn-dev — per-project AI development container. # # Goal: a small, fast-pulling base image (~500 MB target) that gives the AI # (and the user, eventually) a real shell with git, ripgrep, and the # scaffolding to lazy-install language toolchains via mise on first use. # # Heavy toolchains (Node / Python / Go / Rust) are NOT baked in — they # install on demand via `mise install` the first time the AI runs # `npm`, `python`, `go`, etc. This keeps the base image lean and lets us # bump toolchain versions without rebuilding the image. # # Spec is in AI_PATH_B_EXECUTION_PLAN.md §3. FROM ubuntu:24.04 ENV DEBIAN_FRONTEND=noninteractive \ LANG=C.UTF-8 \ LC_ALL=C.UTF-8 \ TZ=UTC # Core OS packages: shell, git, network, build essentials, ripgrep # (powers fs.grep), tini (PID 1 reaper), supervisord (process supervisor # for sshd + dev servers), curl/ca-certs (downloads), unzip (mise # tarballs), sudo (toolchain installers expect it). RUN apt-get update && apt-get install -y --no-install-recommends \ bash coreutils ca-certificates curl wget git openssh-client \ ripgrep jq nano vim less procps lsof net-tools dnsutils \ build-essential pkg-config \ sudo tini supervisor unzip xz-utils \ python3-minimal \ && rm -rf /var/lib/apt/lists/* # vibn user — the AI runs as this, NOT root. RUN useradd --create-home --shell /bin/bash --uid 1000 vibn \ && mkdir -p /workspace /home/vibn/.cache /home/vibn/.local /var/log/vibn-dev \ && chown -R vibn:vibn /workspace /home/vibn /var/log/vibn-dev \ && echo 'vibn ALL=(ALL) NOPASSWD: ALL' > /etc/sudoers.d/vibn # mise — polyglot version manager. Installs Node/Python/Go/Rust on demand. # Pinned to a specific version for reproducibility; bump in this Dockerfile. ENV MISE_VERSION=v2024.12.14 RUN curl -fsSL "https://mise.run" | MISE_VERSION=${MISE_VERSION} sh \ && mv /root/.local/bin/mise /usr/local/bin/mise \ && chmod +x /usr/local/bin/mise # Hook mise into vibn's shell so `node`, `python` etc. resolve once # installed via `mise install`. RUN echo 'eval "$(/usr/local/bin/mise activate bash)"' >> /home/vibn/.bashrc \ && echo 'export PATH="$HOME/.local/bin:$PATH"' >> /home/vibn/.bashrc # Default mise toolchain config — lazily materialised. The AI can # override per-project by writing /workspace/.mise.toml. COPY --chown=vibn:vibn mise.default.toml /home/vibn/.config/mise/config.toml # supervisord runs sshd-less; we don't need ssh in the container because # all exec happens via `docker exec` from the Coolify host. Supervisord # is reserved for dev_server.* (Vite/Next/etc) once that ships. COPY supervisord.conf /etc/supervisor/conf.d/vibn-dev.conf WORKDIR /workspace USER vibn # Keep-alive process. The container's job is to exist; commands run via # `docker exec`. tail -f /dev/null is the canonical "stay running, do # nothing" pattern — cheaper than supervisord for the no-dev-server case. ENTRYPOINT ["/usr/bin/tini", "--"] CMD ["tail", "-f", "/dev/null"]