FROM node:20-bookworm-slim ENV DEBIAN_FRONTEND=noninteractive RUN apt-get update \ && apt-get install -y --no-install-recommends \ bash \ ca-certificates \ curl \ fd-find \ gh \ git \ jq \ make \ openssh-client \ python3 \ python3-pip \ python3-venv \ ripgrep \ rsync \ tmux \ unzip \ wget \ zip \ && rm -rf /var/lib/apt/lists/* \ && pip3 install --break-system-packages --no-cache-dir "litellm[proxy]" -i https://pypi.tuna.tsinghua.edu.cn/simple RUN ln -sf /usr/bin/fdfind /usr/local/bin/fd ARG YQ_VERSION=v4.44.6 RUN wget -q -O /usr/local/bin/yq "https://github.com/mikefarah/yq/releases/download/${YQ_VERSION}/yq_linux_amd64" \ && chmod +x /usr/local/bin/yq ARG TEA_VERSION=0.12.0 RUN wget -q -O /usr/local/bin/tea "https://gitea.com/gitea/tea/releases/download/v${TEA_VERSION}/tea-${TEA_VERSION}-linux-amd64" \ && chmod +x /usr/local/bin/tea RUN npm install -g @anthropic-ai/claude-code # Preflight bypass: replace all Anthropic URLs in the bundled binary with localhost:4008 # (LiteLLM proxy). This is a binary-level patch since the bundled cli.js is minified. RUN python3 - <<'PY' path = "/usr/local/lib/node_modules/@anthropic-ai/claude-code/cli.js" with open(path, "rb") as f: d = bytearray(f.read()) replacements = [ (b"https://api.anthropic.com", b"http://localhost:4008"), (b"https://platform.claude.com", b"http://localhost:4008"), (b"https://claude.ai", b"http://localhost:4008"), (b"api.anthropic.com", b"localhost:4008"), (b"platform.claude.com", b"localhost:4008"), ] total = 0 for old, new in replacements: c = d.count(old) if c: d = d.replace(old, new) total += c d = d.replace(b"https://localhost:4008", b"http://localhost:4008") with open(path, "wb") as f: f.write(d) # Verify with open(path, "rb") as f: d = f.read() remaining = sum(d.count(p) for p in [b"api.anthropic.com", b"platform.claude.com"]) if remaining: raise SystemExit(f"Patch incomplete: {remaining} anthropic refs remain") print(f"Patched {total} Anthropic URL refs → localhost:4008") PY CMD ["bash"]