spacehub

surshar / claude-code

Claude Code is an agentic coding tool that lives in your terminal, understands your codebase, and helps you code faster by executing routine tasks, explaining complex code, and handling git workflows - all through natural language commands.

Built by Anthropic · github.com/anthropics

claude-code / examples / gateway / aws / Dockerfile
67 lines · 3.1 KBRaw
1# Runtime image for `claude gateway`.
2#
3# This image does NOT build the binary. It expects a prebuilt native
4# linux-x64 `claude` executable in the build context — the Claude Code release
5# binary, which includes the `gateway` subcommand. setup.sh places it at
6# ./claude (downloading and checksum-verifying it via DIST_URL/DIST_SHA256 if
7# missing). Override CLAUDE_BINARY to point at a different path.
8#
9# Unlike the GCP example (which mounts the config from Secret Manager at
10# runtime), this image BAKES gateway.yaml in at /etc/claude/gateway.yaml — on
11# ECS the task definition injects only the secrets the YAML references, as env
12# vars. gateway.yaml therefore must be fully filled in (no REPLACE_ME) before
13# building; setup.sh enforces this. A config edit means a rebuild under a new
14# tag. The file contains no secret values — every credential resolves at boot
15# via ${ENV_VAR} expansion.
16#
17# The image also bakes in the AWS RDS CA bundle (rds-global-bundle.pem —
18# setup.sh downloads it from https://truststore.pki.rds.amazonaws.com before
19# the build) and trusts it via NODE_EXTRA_CA_CERTS, so the store connection
20# string's `?sslmode=verify-full` verifies the RDS server certificate chain
21# and hostname. NOTE the gateway's driver reads `sslmode` from the URL but NOT
22# a libpq-style `sslrootcert=` param — the CA must come from this env var.
23#
24# Build:
25# docker build --platform=linux/amd64 --provenance=false \
26# --build-arg CLAUDE_BINARY=./claude -t claude-gateway .
27#
28# (For Fargate on ARM64/Graviton: build --platform=linux/arm64 with the
29# linux-arm64 binary and set the task definition's cpuArchitecture to ARM64.)
30#
31# Run:
32# docker run --rm -p 8080:8080 \
33# -e OIDC_CLIENT_SECRET -e GATEWAY_JWT_SECRET -e GATEWAY_POSTGRES_URL \
34# claude-gateway
35
36ARG CLAUDE_BINARY=./claude
37ARG GATEWAY_CONFIG=./gateway.yaml
38ARG RDS_CA_BUNDLE=./rds-global-bundle.pem
39
40# distroless/cc provides glibc + libstdc++ (required by the Bun-compiled
41# native binary). The :nonroot tag runs as uid/gid 65532. Pinned by digest so
42# the build never silently takes new upstream bytes (the digest is the
43# multi-arch OCI index, so --platform still selects amd64/arm64). To refresh
44# the pin after reviewing upstream changes:
45# docker manifest inspect -v gcr.io/distroless/cc-debian12:nonroot # prints the index digest
46FROM gcr.io/distroless/cc-debian12:nonroot@sha256:ce0d66bc0f64aae46e6a03add867b07f42cc7b8799c949c2e898057b7f75a151
47
48ARG CLAUDE_BINARY
49ARG GATEWAY_CONFIG
50ARG RDS_CA_BUNDLE
51COPY --chmod=0755 ${CLAUDE_BINARY} /usr/local/bin/claude
52# WORKDIR pre-creates /etc/claude with 0755 — without it, COPY --chmod would
53# also stamp the auto-created parent directory 0644 (no execute bit), making
54# the config unreadable for the nonroot user.
55WORKDIR /etc/claude
56COPY --chmod=0644 ${GATEWAY_CONFIG} /etc/claude/gateway.yaml
57COPY --chmod=0644 ${RDS_CA_BUNDLE} /etc/claude/rds-global-bundle.pem
58WORKDIR /
59
60ENV CLAUDE_CONFIG_DIR=/tmp/.claude
61# Trust anchor for the store's sslmode=verify-full (see header comment).
62ENV NODE_EXTRA_CA_CERTS=/etc/claude/rds-global-bundle.pem
63
64EXPOSE 8080
65USER nonroot
66
67ENTRYPOINT ["/usr/local/bin/claude", "gateway", "--config", "/etc/claude/gateway.yaml"]