tool-containers
Menu
GitHub (opens in new tab)

Run Claude Code with Helm

The chart/ installs Claude Code as a Job that runs claude once with the arguments in args and exits.

Images
  • GHCRghcr.io/hambn/claude-code
  • Docker Hubdocker.io/hambn/claude-code
Use case
One-shot review in a cluster from a Helm chart
Upstream
github.com/anthropics/claude-code (opens in new tab)
Source
tools/ai/claude-code/docs/helm (opens in new tab)
On this page

Prerequisites

  • Helm 3.10 or later, for --set-json, and a Kubernetes cluster.
  • An Anthropic API key.

Install

Shell
kubectl create secret generic claude-code --from-literal=ANTHROPIC_API_KEY="$ANTHROPIC_API_KEY"
helm install claude-code ./chart
kubectl logs -f job/claude-code-claude-code

Set a different prompt at install time:

Shell
helm install claude-code ./chart --set-json 'args=["-p","list the failing tests"]'

Values

Value Default Purpose
image.repository ghcr.io/hambn/claude-code Image repository.
image.tag ubuntu-browser Image tag. Use ubuntu-browser@sha256:<digest> to pin one build.
image.pullPolicy Always Pull policy.
args ["-p", "review the workspace"] Arguments passed to claude.
apiKeySecret claude-code Secret that holds the ANTHROPIC_API_KEY key.
resources 100m CPU and 256Mi requested, 1 CPU and 1Gi limit Container resources.

Workspace

/workspace is an empty emptyDir that is deleted with the pod. Mount your code into it by editing the volume in chart/templates/job.yaml, for example with a PersistentVolumeClaim or a cloning init container.

Files

Cleanup

Shell
helm uninstall claude-code
kubectl delete secret claude-code

A Job's pod template cannot change, so uninstall the release before installing a new run.

File contents

chart/Chart.yaml6 lines
apiVersion: v2
name: claude-code
description: Claude Code CLI as a one-shot Job
type: application
version: 0.2.0
appVersion: "2.1.282"
chart/values.yaml18 lines
image:
  repository: ghcr.io/hambn/claude-code
  tag: ubuntu-browser
  pullPolicy: Always

# Claude Code args.
args: ["-p", "review the workspace"]

# Name of an existing Secret holding key ANTHROPIC_API_KEY.
apiKeySecret: claude-code

resources:
  requests:
    cpu: 100m
    memory: 256Mi
  limits:
    cpu: "1"
    memory: 1Gi
chart/templates/job.yaml39 lines
apiVersion: batch/v1
kind: Job
metadata:
  name: {{ .Release.Name }}-claude-code
spec:
  backoffLimit: 0
  template:
    spec:
      restartPolicy: Never
      securityContext:
        runAsNonRoot: true
        runAsUser: 1000
        runAsGroup: 1000
        fsGroup: 1000
        seccompProfile:
          type: RuntimeDefault
      containers:
        - name: claude
          image: "{{ .Values.image.repository }}:{{ .Values.image.tag }}"
          imagePullPolicy: {{ .Values.image.pullPolicy }}
          args: {{ toJson .Values.args }}
          securityContext:
            allowPrivilegeEscalation: false
            capabilities:
              drop: ["ALL"]
          resources:
            {{- toYaml .Values.resources | nindent 12 }}
          env:
            - name: ANTHROPIC_API_KEY
              valueFrom:
                secretKeyRef:
                  name: {{ .Values.apiKeySecret }}
                  key: ANTHROPIC_API_KEY
          volumeMounts:
            - name: workspace
              mountPath: /workspace
      volumes:
        - name: workspace
          emptyDir: {}

Topics