66 lines
2.6 KiB
Docker
66 lines
2.6 KiB
Docker
# syntax=docker/dockerfile:1.7
|
|
#
|
|
# Two stages: a uv-based builder that resolves the venv, and a thin
|
|
# python:3.13-slim runtime with bun + the `claude` CLI baked in.
|
|
#
|
|
# Alpine is intentionally avoided: @anthropic-ai/claude-code ≥ 2.1.113
|
|
# ships a glibc-only native binary (anthropics/claude-code#50270).
|
|
#
|
|
# This image is deliberately un-opinionated about ports and command —
|
|
# the consumer's compose file decides what to publish and how to invoke.
|
|
|
|
# ---- Builder: uv + Python deps ----
|
|
FROM ghcr.io/astral-sh/uv:python3.13-bookworm-slim AS builder
|
|
ENV UV_LINK_MODE=copy \
|
|
UV_COMPILE_BYTECODE=1 \
|
|
UV_PYTHON_DOWNLOADS=never
|
|
# `git` is required at build time: the `prod` extra resolves
|
|
# raycast-api / claude-code-api from git URLs.
|
|
RUN apt-get update \
|
|
&& apt-get install -y --no-install-recommends git \
|
|
&& rm -rf /var/lib/apt/lists/*
|
|
WORKDIR /app
|
|
|
|
RUN --mount=type=cache,target=/root/.cache/uv \
|
|
--mount=type=bind,source=uv.lock,target=uv.lock \
|
|
--mount=type=bind,source=pyproject.toml,target=pyproject.toml \
|
|
uv sync --frozen --no-dev --no-install-project --extra prod
|
|
|
|
COPY . /app
|
|
RUN --mount=type=cache,target=/root/.cache/uv \
|
|
uv sync --frozen --no-dev --extra prod
|
|
|
|
# ---- Runtime ----
|
|
FROM python:3.13-slim AS runtime
|
|
RUN apt-get update \
|
|
&& apt-get install -y --no-install-recommends ca-certificates git \
|
|
&& rm -rf /var/lib/apt/lists/*
|
|
|
|
# Bun native binary (glibc) — fast `npm install` replacement, only used
|
|
# to drop the claude CLI into the image. Not invoked at runtime.
|
|
COPY --from=oven/bun:1-slim /usr/local/bin/bun /usr/local/bin/bun
|
|
RUN ln -s /usr/local/bin/bun /usr/local/bin/bunx
|
|
|
|
# `--trust` is required: without it bun skips the postinstall step that
|
|
# fetches claude's native binary (anthropics/claude-code#50203). The
|
|
# postinstall itself is bun's smoke check — if it fails the layer
|
|
# fails. We deliberately DO NOT run `claude --version` here: claude
|
|
# touches `$HOME` on every invocation (creates `/root/.claude/`,
|
|
# `/root/.claude.json`, sometimes `/root/.config/claude/`), and those
|
|
# build-time artifacts seed the runtime named-volume `claude-home`
|
|
# with stale "haven't onboarded" state, so the user gets re-prompted
|
|
# for trust/bypass dialogs on every rebuild and the subscription auth
|
|
# can land on a tainted credential file.
|
|
ENV BUN_INSTALL=/usr/local/bun-global \
|
|
PATH=/usr/local/bun-global/bin:/app/.venv/bin:$PATH
|
|
RUN bun install -g --trust @anthropic-ai/claude-code \
|
|
&& test -x "$(command -v claude)" \
|
|
&& rm -rf /root/.claude /root/.claude.json /root/.config/claude
|
|
|
|
COPY --from=builder /app/.venv /app/.venv
|
|
COPY --from=builder /app /app
|
|
WORKDIR /app
|
|
|
|
ENTRYPOINT ["python", "-m"]
|
|
CMD ["beaver_gateway"]
|