Sign inSign up

n8500x/claude-code

By n8500x

Updated 4 days ago

Claude Code on-prem: OpenAI/Anthropic gateways (API key, no-auth or OIDC) + Bedrock.

Image
0

10K+

n8500x/claude-code repository overview

claude-code (Bedrock)

The Claude Code agentic CLI, containerized to run against AWS Bedrock — either directly (SigV4) or through an on-prem gateway that fronts Bedrock with OAuth2 auth. Ships with a Java + Python build toolchain and an autonomous agentic-loop mode.

The docs are baked into the image. Run docker run --rm n8500x/claude-code help for a cheat sheet, or docs for this full document — no credentials needed.

Jump to: Quick reference · Gateway auth (SSO) · Air-gapped · Jenkins · Troubleshooting

Overview

Anthropic's official @anthropic-ai/claude-code CLI in a slim Node runtime. Defaults to Bedrock (CLAUDE_CODE_USE_BEDROCK=1); set gateway vars to use your on-prem gateway instead (Anthropic- or OpenAI-shaped). Entrypoint launches the TUI in /workspace; -p "..." for headless, loop for autonomous. Telemetry/updater off by default — suits air-gapped networks.

Quick reference

The image is self-documenting — help (cheat sheet) and docs (this file) run with no credentials:

docker run --rm n8500x/claude-code help
docker run --rm n8500x/claude-code docs
I want to…Command
Interactive session (Bedrock)docker run --rm -it -e AWS_REGION=us-east-1 -e AWS_ACCESS_KEY_ID -e AWS_SECRET_ACCESS_KEY -e AWS_SESSION_TOKEN -v "$PWD:/workspace" n8500x/claude-code
One-shot prompt… n8500x/claude-code -p "explain this repo"
Autonomous loop… n8500x/claude-code loop "make ./gradlew test pass"
Use JDK 17add -e JAVA_HOME=/opt/java-17
No permission promptsadd -e CLAUDE_YOLO=1
Via on-prem gateway (SSO)set -e CLAUDE_GATEWAY_URL=… -e OIDC_ISSUER_URL=… -e OIDC_REALM=… -e GATEWAY_CLIENT_ID=… -e GATEWAY_CLIENT_SECRET=…
Show the cheat sheet / full docs… n8500x/claude-code help / docs

Podman works too — it's a drop-in for docker; use podman run … in place of docker run … in every example below.

Clone a private repo over SSH (and use its skills)

Inject an SSH key and optionally auto-clone a repo into /workspace — to pull code to review and pick up the repo's Claude skills (.claude/skills/, auto-discovered):

docker run --rm \
  -e GIT_SSH_KEY_FILE=/keys/id -v ~/.ssh/id_ed25519:/keys/id:ro \
  -e CLONE_REPO='[email protected]:org/repo.git' \
  -v "$PWD:/workspace" [AUTH ENV…] \
  n8500x/claude-code -p "review this repo"

Key via GIT_SSH_KEY (raw), GIT_SSH_KEY_B64, or GIT_SSH_KEY_FILE; host keys via GIT_SSH_KNOWN_HOSTS[_FILE] / GIT_SSH_STRICT (default accept-new). Clone lands in /workspace (or CLONE_DIR), the entrypoint cds in so the repo's .claude/skills/ are active; CLONE_REF/CLONE_DEPTH set branch/shallow.

Quick start

docker pull n8500x/claude-code, then copy a complete command from Recipes. Interactive TUI needs -it; -p "…" runs headless; add -e AWS_PROFILE=… -v "$HOME/.aws:/home/claude/.aws:ro" for a named AWS profile.

Autonomous agentic loop

The loop subcommand runs Claude Code autonomously — headless, permissions bypassed — re-engaging the same session each iteration until the goal is verified done or a cap is hit. No TTY needed, so it suits CI / batch use. Same env as above (Bedrock or gateway), plus:

docker run --rm -v "$PWD:/workspace" [AUTH ENV…] \
  n8500x/claude-code loop "make ./gradlew test pass"

The task can also come from -e CLAUDE_TASK="..." or a /workspace/TASK.md file. CLAUDE_LOOP=1 turns any invocation into a loop.

How it stops. Each iteration runs claude -p --output-format json --dangerously-skip-permissions resuming a fixed session id, so context carries over. An appended system prompt makes it emit CLAUDE_TASK_COMPLETE only when verified done. Ends on: sentinel (0), CLAUDE_LOOP_MAX_ITERS (4), budget (3), errors (1), or /workspace/.claude-stop. JSON logs in /workspace/.claude-loop/. It edits unattended — only use repos you trust.

What's inside

  • Base image: node:22-alpine; Maven's plexus-utils and npm's bundled deps patched → the image scans at ZERO high/critical CVEs.
  • Agent: @anthropic-ai/claude-code via npm (CLAUDE_CODE_VERSION, pinned 2.1.220) as claude.
  • System tools: git, ripgrep (Claude Code's search backend), openssh-client, bash, openssl, unzip, ca-certificates.
  • Python: python3 with pip (python aliased). PEP 668 — use a venv.
  • Java toolchain: OpenJDK 17 (/opt/java-17) and 21 (/opt/java-21), /opt/java → 21 default (JAVA_HOME), plus Gradle 9.7.1 (GRADLE_HOME; scripts clean of deprecation warnings on Gradle 8 run unchanged). Switch JDK per run with -e JAVA_HOME=/opt/java-17 (entrypoint re-prepends $JAVA_HOME/bin to PATH; Gradle honours JAVA_HOME). Checksum-verified; override with --build-arg GRADLE_VERSION=x.y.
  • User / working dir: runs as non-root claude; working directory is /workspace; config lives in /home/claude/.claude.
  • Entrypoint: /usr/local/bin/claude-entrypoint — enables Bedrock and execs claude "$@", or routes to the autonomous loop runner on the loop subcommand / CLAUDE_LOOP=1.
  • Loop runner: /usr/local/bin/claude-agent-loop — drives Claude Code autonomously (see Autonomous agentic loop).
  • Token helper: /usr/local/bin/claude-token — SSO / OIDC OAuth2 client-credentials helper for on-prem gateway auth (see On-prem gateway auth).

Configuration

On-prem gateway auth

Gateway mode engages when CLAUDE_GATEWAY_URL is set. Auth is whichever you provide: GATEWAY_API_KEY (static key), GATEWAY_NO_AUTH=1 (none), or GATEWAY_CLIENT_ID/GATEWAY_CLIENT_SECRET + OIDC_ISSUER_URL (OAuth2 client-credentials, token auto-refreshed per CLAUDE_CODE_API_KEY_HELPER_TTL_MS and on any 401). The token endpoint is <OIDC_ISSUER_URL>/realms/<OIDC_REALM>/protocol/openid-connect/token (realm defaults to master), or set GATEWAY_TOKEN_URL which is used verbatim. See Recipes.

Recipes — copy/paste for each on-prem setup

Pick the one that matches your endpoint. Every example is complete: substitute the URLs/keys and run.

1. On-prem OpenAI-compatible model (GLM, vLLM, Ollama, LM Studio) — API key, no OAuth

podman run --rm -v "$PWD:/workspace"   -e GATEWAY_PROTOCOL=openai   -e CLAUDE_GATEWAY_URL=http://glm.internal:8000   -e GATEWAY_API_KEY=sk-your-key   -e ANTHROPIC_MODEL=glm-4.6   n8500x/claude-code -p "explain this repo"

2. Same, but the endpoint needs no auth at all

podman run --rm -v "$PWD:/workspace"   -e GATEWAY_PROTOCOL=openai   -e CLAUDE_GATEWAY_URL=http://vllm.internal:8000   -e GATEWAY_NO_AUTH=1   -e ANTHROPIC_MODEL=qwen2.5-coder   n8500x/claude-code -p "explain this repo"

3. Corporate gateway fronting Bedrock, OAuth2 via SSO

podman run --rm -v "$PWD:/workspace"   -e GATEWAY_PROTOCOL=openai   -e CLAUDE_GATEWAY_URL=https://agent-gw.internal   -e GATEWAY_TOKEN_URL=https://sso.internal/realms/prod/protocol/openid-connect/token   -e GATEWAY_CLIENT_ID=my-client -e GATEWAY_CLIENT_SECRET=my-secret   -e GATEWAY_COOKIE='ROUTEID=abc'   -e CLAUDE_CA_CERT=/certs/ca.pem -v /etc/pki/ca.pem:/certs/ca.pem:ro   -e ANTHROPIC_MODEL='anthropic.claude-3-7-sonnet-20250219-v1:0'   n8500x/claude-code -p "explain this repo"

4. Gateway that speaks the Anthropic API natively (/v1/messages)

podman run --rm -v "$PWD:/workspace"   -e GATEWAY_PROTOCOL=anthropic   -e CLAUDE_GATEWAY_URL=https://agent-gw.internal   -e GATEWAY_API_KEY=sk-your-key   -e ANTHROPIC_MODEL='anthropic.claude-3-7-sonnet-20250219-v1:0'   -e CLAUDE_BRIDGE_ALWAYS=1   n8500x/claude-code -p "explain this repo"

(CLAUDE_BRIDGE_ALWAYS=1 keeps the bridge in the path for request logging without translating anything — drop it for a direct connection.)

5. Autonomous Java codegen from a private repo's skills

podman run --rm --user root -v "$PWD:/workspace"   -e CLAUDE_PROFILE=java -e CLAUDE_JAVA=17   -e GATEWAY_PROTOCOL=openai -e CLAUDE_GATEWAY_URL=http://glm.internal:8000   -e GATEWAY_API_KEY=sk-your-key -e ANTHROPIC_MODEL=glm-4.6   -e GIT_SSH_KEY_FILE=/keys/id -v ~/.ssh/id_ed25519:/keys/id:ro   -e CLONE_REPO='[email protected]:org/repo.git'   -e CLAUDE_SHOW_CODE=1   n8500x/claude-code loop "Using the skill in .claude/skills, generate the REST layer"

6. Bedrock directly (no gateway)

podman run --rm -v "$PWD:/workspace"   -e AWS_REGION=us-east-1   -e AWS_ACCESS_KEY_ID -e AWS_SECRET_ACCESS_KEY -e AWS_SESSION_TOKEN   -e ANTHROPIC_MODEL='us.anthropic.claude-3-7-sonnet-20250219-v1:0'   n8500x/claude-code -p "explain this repo"

Auth is chosen by what you set — no flag needed:

You setAuth used
GATEWAY_API_KEYstatic bearer token, no SSO
GATEWAY_NO_AUTH=1none
GATEWAY_CLIENT_ID + SECRET + (OIDC_ISSUER_URL or GATEWAY_TOKEN_URL)OAuth2 client-credentials, auto-refreshed
nothing gateway-ishAWS Bedrock (SigV4)

Debugging: -e CLAUDE_DEBUG=1 (full trace) or -e BRIDGE_LOG_BODY=1 (request/response bodies).

Gateway protocol switch (Anthropic or OpenAI)

Set only the base URL and pick the protocol with one switch — it selects both the endpoint path and the message JSON format:

GATEWAY_PROTOCOLClaude talks toJSON
anthropic (default)<base>/v1/messagesnative, no bridge
openai<base>/v1/chat/completionstranslated by the built-in bridge
-e GATEWAY_PROTOCOL=openai -e CLAUDE_GATEWAY_URL=https://agent-gw.internal      # base URL only

The URL is normalised: if you include /v1/messages or /v1/chat/completions it's stripped (and the matching protocol auto-selected), so paths can never double up. Override the upstream path with GATEWAY_CHAT_PATH. Startup prints what it resolved:

protocol: openai — Claude /v1/messages → bridge → https://agent-gw.internal/v1/chat/completions (JSON translated)

The bridge translates tool calls and SSE streaming both ways, and logs each rewrite in colour (▶ REWRITE … → OpenAI POST …). CLAUDE_DEBUG=1 adds the translated JSON; gateway errors print in red with the verbatim body. CLAUDE_TRACE=1 (either protocol) logs raw request/response.

Tell-tale that you need openai: the gateway replies Cannot POST /v1/messages.

Gateway compatibility & payload control

Applied automatically (no flags):

FixEffect
context_management strippedremoves an unknown top-level field
metadata.user_id coerced to stringsome gateways reject object ids

Disable with -e BRIDGE_COMPAT=0; add fields via -e BRIDGE_STRIP_FIELDS="a b".

To shrink the request (the → model · …KB line shows what's sent):

VariableEffect
BRIDGE_ONLY_TOOLS="Bash"send only these tool schemas
BRIDGE_SLIM_TOOLS=1reduce tool schemas to required params only
BRIDGE_MAX_TOOL_DESC=80truncate tool descriptions
BRIDGE_MAX_SYSTEM_CHARS=400truncate Claude's system prompt
BRIDGE_SYSTEM_PROMPT="…"replace the system prompt (used verbatim)
BRIDGE_DROP_SYSTEM=1drop the system prompt entirely
BRIDGE_NO_TOOLS=1drop all tools (diagnostic only — agent can't act)
BRIDGE_BASH_DESC="…"override the Bash tool description
CLAUDE_PROFILE=gradlepreset: Bash-only, slim schemas, short prompt (~1KB)
Baked Gradle plugins & run artifacts

The image pre-bakes Spotless com.diffplug.spotless 7.1.0 into a shared Gradle cache (GRADLE_USER_HOME=/opt/gradle-home), so air-gapped builds resolve it offline (gradle --offline works; add plugins via --build-arg SPOTLESS_VERSION=… or the same warm pattern).

Loop artifacts land in the directory Claude started in (the cloned repo when CLONE_REPO is used): claude-report.html (tokens, cost, tool calls, diff), claude-status.json (machine-readable for the pipeline), and the final commit (never pushed — CI owns the push). Override with CLAUDE_REPORT_FILE / CLAUDE_STATUS_FILE; skip with CLAUDE_REPORT=0 / CLAUDE_COMMIT=0.

Long-running builds

Claude Code's Bash tool defaults to a 2-minute timeout, which kills a real Gradle/Maven build. The image raises it (all overridable):

VariableDefaultPurpose
BASH_DEFAULT_TIMEOUT_MS600000 (10 min)default per command
BASH_MAX_TIMEOUT_MS3600000 (1 h)ceiling the model may request
BASH_MAX_OUTPUT_LENGTH200000max captured command output
Surviving gateway/route timeouts (504)

A route that caps request duration (OpenShift HAProxy: 30s) 504s before a long completion finishes. The bridge retries and shrinks to fit:

VariableDefaultPurpose
BRIDGE_RETRIES2retries on 502/503/504/408/429 and read timeouts
BRIDGE_RETRY_BACKOFF2seconds, doubles each retry
BRIDGE_RETRY_SHRINK1halve max_tokens per retry (0 to keep it)
BRIDGE_MAX_TOKENScap up front; the preventive half
BRIDGE_TIMEOUT600our own client timeout (seconds)
BRIDGE_LOG_FILEtty→/tmp/claude-bridge.logbridge log target (TUI auto-redirects)

Keep BRIDGE_STREAM=true/auto — streaming responses are far less likely to hit router timeouts.

Small context windows (GLM 131k etc.)

A model with a window under Claude's assumed ~200k 400s as the conversation grows. Set -e CLAUDE_CONTEXT_LIMIT=131072. Then: (1) Claude auto-compacts its own session — after a bridge compaction ~98% of the window is reported as input usage, so Claude summarizes its own history. (2) The bridge compacts oversized requests (system + task + recent turns), proactively and on 400s. (3) Dropped turns are summarized via a gateway call into the note. In loop mode, an iteration that hit compaction makes the next one start a FRESH session re-deriving state from the repo (resuming an over-window session loops forever). BRIDGE_CONTEXT_COMPACT=0/BRIDGE_COMPACT_SUMMARY=0 disable (2)/(3); BRIDGE_TOKEN_RATIO tunes the chars-per-token estimate (3 when CLAUDE_CONTEXT_LIMIT is set, else 4).

Bedrock model selection

ANTHROPIC_MODEL is unset by default (CLI uses its Bedrock defaults). Pin one with -e ANTHROPIC_MODEL='us.anthropic.claude-...-v1:0'. The model must be enabled in AWS_REGION, and the ID is usually an inference-profile ID (us./eu./apac. prefix), not a bare foundation-model ID.

Environment variables
VariableDefaultPurpose
JAVA_HOME/opt/java (→ 21)Active JDK. Override per run, e.g. -e JAVA_HOME=/opt/java-17; the entrypoint puts $JAVA_HOME/bin first on PATH.
JAVA_17_HOME / JAVA_21_HOME/opt/java-17 / /opt/java-21Fixed paths to each JDK.
GRADLE_HOMEGradle 9.7.1.current Gradle.
CLAUDE_CODE_USE_BEDROCK1Route the Anthropic protocol to AWS Bedrock.
AWS_REGIONus-east-1Bedrock region hosting the target model.
AWS_ACCESS_KEY_ID / AWS_SECRET_ACCESS_KEY / AWS_SESSION_TOKENCredentials (standard AWS SDK chain).
AWS_PROFILENamed profile; mount ~/.aws to /home/claude/.aws.
AWS_BEARER_TOKEN_BEDROCKBedrock API key, as an alternative to SigV4 creds.
ANTHROPIC_MODEL / ANTHROPIC_SMALL_FAST_MODELCLI defaultPin Bedrock inference profiles.
CLAUDE_YOLOunsetIf 1, adds --dangerously-skip-permissions to interactive/-p runs (no tool prompts).
CLAUDE_USE_BEDROCK1Set to 0 to unset CLAUDE_CODE_USE_BEDROCK (use direct API / a gateway instead).
Agentic loop(used by the loop subcommand / CLAUDE_LOOP=1)
CLAUDE_LOOP0If 1, run the autonomous loop instead of a normal session.
CLAUDE_TASK / CLAUDE_TASK_FILE— / /workspace/TASK.mdThe goal, inline or from a file (CLI args win over both).
CLAUDE_LOOP_MAX_ITERS25Outer-loop iteration cap.
CLAUDE_MAX_BUDGET_USD / CLAUDE_LOOP_MAX_BUDGET_USDPer-iteration and cumulative spend caps (USD).
CLAUDE_DONE_SENTINELCLAUDE_TASK_COMPLETELine the agent emits to signal completion.
CLAUDE_LOOP_MAX_ERRORS3Abort after this many consecutive failed iterations.
CLAUDE_STOP_FILE / CLAUDE_LOG_DIR/workspace/.claude-stop / /workspace/.claude-loopGraceful-stop trigger and per-iteration JSON logs.
CLAUDE_MODELPassed through as --model (loop mode).
DISABLE_AUTOUPDATER / DISABLE_TELEMETRY / DISABLE_ERROR_REPORTING / CLAUDE_CODE_DISABLE_NONESSENTIAL_TRAFFIC1Disable phone-home / auto-update for restricted networks.
Mounts
PathPurpose
/workspaceYour project directory (working dir).
/home/claude/.claudeClaude Code config/state — mount a named volume to persist across runs.
/home/claude/.awsMount ~/.aws (read-only) when using AWS_PROFILE.

Air-gapped / on-prem deployment

Runs fully offline against only your internal gateway or a Bedrock VPC endpoint.

Self-contained at runtime. CLI, toolchain, token helper and docs are baked in — nothing is fetched at start. Prove it: docker run --rm --network none n8500x/claude-code help. Telemetry, error reporting and the auto-updater are off by default.

Private CA (usually required). Internal SSO / gateways present a corporate-CA cert. Mount it at run time — -e CLAUDE_CA_CERT=/certs/ca.pem -v /path/ca.pem:/certs/ca.pem:ro — and both hops trust it; or bake it at build by dropping *.crt into certs/. -e CLAUDE_TLS_INSECURE=1 skips verification on trusted networks.

Distribute offline: docker save n8500x/claude-code | gzip > cc.tar.gz, copy across the gap, docker load < cc.tar.gz.

Building your projects needs internal mirrors — the image ships toolchains, not a dep cache. Gradle: use the baked gradle (not ./gradlew) + internal Maven repo. npm/pip: point at your registry.

Running in Jenkins (CI)

Wrap any recipe in a sh step. No -it (no TTY); use -p "PROMPT" or loop "GOAL". Feed credentials from Jenkins Credentials, e.g. withCredentials([string(credentialsId: 'gateway-api-key', variable: 'GW_KEY')]) then -e GATEWAY_API_KEY="$GW_KEY".

sh '''
  docker run --rm --user root -v "$WORKSPACE:/workspace" \
    -e GATEWAY_PROTOCOL=openai -e CLAUDE_GATEWAY_URL=https://gw.internal \
    -e GATEWAY_API_KEY="$GW_KEY" -e ANTHROPIC_MODEL=glm-4.6 \
    n8500x/claude-code -p "Review the diff and add missing unit tests."
'''

Notes: exit codes drive stage pass/fail (loop: 0 done / 4 max-iters / 3 budget / 1 errors); --user root (or --user "$(id -u):$(id -g)" -e HOME=/tmp) to write $WORKSPACE; pre-load the image on air-gapped agents.

Build

docker build -t n8500x/claude-code .

To bake a private CA, drop *.crt into certs/ before building:

cp corp-root-ca.crt certs/ && docker build -t n8500x/claude-code .

Override the pinned CLI version:

docker build \
  --build-arg CLAUDE_CODE_VERSION=2.1.220 \
  -t n8500x/claude-code .

Troubleshooting

First step for any auth issue: re-run with -e CLAUDE_DEBUG=1 — it prints the auth-mode decision, the exact SSO token endpoint, the client-credentials POST + HTTP status, and the token length, so the failing hop is obvious.

SymptomLikely cause / fix
API Error: AWS default-chain credential resolve timed outGateway mode didn't engage, so it fell back to Bedrock and the AWS SDK probed EC2 metadata. Make sure both CLAUDE_GATEWAY_URL and the client id/secret are set (that pair alone now forces gateway mode), plus OIDC_ISSUER_URL (realm defaults to master). Run with -e CLAUDE_DEBUG=1 and check the ==> auth mode: line. This image disables EC2 IMDS by default so the hang is now an instant error; genuine EC2-role Bedrock users set -e AWS_EC2_METADATA_DISABLED=false.
gateway mode: SSO token request failed at startupThe SSO client-credentials exchange failed. Check GATEWAY_CLIENT_ID/SECRET, OIDC_ISSUER_URL/OIDC_REALM (or GATEWAY_TOKEN_URL), and GATEWAY_AUTH_STYLE (post vs basic). Test in isolation with debug: docker run --rm -e CLAUDE_DEBUG=1 -e OIDC_ISSUER_URL=… -e GATEWAY_CLIENT_ID=… -e GATEWAY_CLIENT_SECRET=… --entrypoint claude-token n8500x/claude-code.
HTTP 404 from the SSO token endpointEither the realm/URL is wrong, or the SSO front-end (load balancer/route) needs a routing/session cookie — add -e GATEWAY_COOKIE='ROUTEID=…' (or -e GATEWAY_TOKEN_HEADERS='Cookie: …'). Creds go in the body as grant_type/client_id/client_secret (the default post style).
Unauthorized / 401 from the gateway (after SSO succeeds)SSO worked and the token reaches the gateway as Authorization: Bearer (verified) — the gateway is rejecting the token's claims, usually the wrong audience/scope. Ask your gateway team what it requires and set -e GATEWAY_SCOPE='…' (and/or -e GATEWAY_AUDIENCE=…); run -e CLAUDE_DEBUG=1 and compare the token claims: … aud=… scope=… line to that. If the gateway also needs a routing cookie, it's auto-forwarded from GATEWAY_COOKIE.
Cannot POST /v1/messages (or every request 404s)Gateway is OpenAI-shaped: set -e GATEWAY_PROTOCOL=openai (see protocol switch). -e CLAUDE_TRACE=1 prints the gateway's verbatim error.
issue with the selected model / not a recognized model id / model does not existClaude validates the selected model name, so ANTHROPIC_MODEL must not hold a raw Bedrock id. Gateway mode handles it: set -e ANTHROPIC_MODEL='<your Bedrock id>' and the image moves it into ANTHROPIC_DEFAULT_{OPUS,SONNET,HAIKU}_MODEL and leaves ANTHROPIC_MODEL unset — Claude selects a recognized tier and sends your id. (Equivalently, set the three ANTHROPIC_DEFAULT_*_MODEL yourself and don't set ANTHROPIC_MODEL.) The printed settings.json shows only those three.
claude hangs / times out after auth: gatewayThe gateway isn't reachable — the startup probe prints gateway: CANNOT reach host:port. Check the URL/firewall, set HTTP_PROXY/HTTPS_PROXY if a proxy is needed, and confirm CLAUDE_GATEWAY_URL host+port.
Auth/401 errors talking to the gateway after it startsToken endpoint returns a token but the gateway rejects it — verify CLAUDE_GATEWAY_URL path and that the token's scope/audience is accepted. Add routing headers with ANTHROPIC_CUSTOM_HEADERS.
certificate verify failed / self-signed certificate (SSO or gateway)Your private CA isn't trusted. Mount it and set -e CLAUDE_CA_CERT=/certs/ca.pem -v /path/ca.pem:/certs/ca.pem:ro — the entrypoint builds a combined bundle trusted by both the SSO (Python) and gateway (Node) hops. Or bake it at build (drop into certs/). Trusted-network unblock: -e CLAUDE_TLS_INSECURE=1.
Bedrock: could not load credentials / AccessDeniedCredentials not reaching the container or the model isn't enabled in AWS_REGION. Pass AWS_* env or mount ~/.aws with AWS_PROFILE; confirm the model/inference-profile is enabled in that region.
model … not found / ValidationExceptionSet ANTHROPIC_MODEL to a valid inference-profile id (us./eu./apac. prefix) enabled in your region.
The TUI looks garbled / exits immediatelyInteractive mode needs a TTY — run with -it. For non-TTY contexts use -p or loop.
Loop never stops / stops too earlyTune CLAUDE_LOOP_MAX_ITERS; the agent must print CLAUDE_TASK_COMPLETE to finish. Inspect per-iteration JSON in /workspace/.claude-loop/.
Java build uses the wrong JDKSet -e JAVA_HOME=/opt/java-17 (or /opt/java-21). Gradle follows JAVA_HOME.

Notes

  • Bedrock access is assumed to be reachable from the container — over the internet or a VPC/PrivateLink endpoint for air-gapped setups. This image does not bundle a model backend.
  • --dangerously-skip-permissions (CLAUDE_YOLO=1) runs every tool without prompting. Only point it at workspaces you trust.
  • Credentials never bake into the image — they come in at run time via env or a mounted ~/.aws.

Tag summary

Content type

Image

Digest

sha256:5fbd1c5c5

Size

638.1 MB

Last updated

4 days ago

docker pull n8500x/claude-code