Share Claude Code configuration with PVC direct mount
Both /home/user/.claude/ and /home/user/.claude.json are mounted directly from a dedicated PVC. All changes persist automatically.
The direct mount flow:
-
A one-time init pod creates an empty skeleton on the PVC:
{}in.claude.jsonand an empty.claude/directory. -
The first workspace starts. The PVC mounts to
/home/user/.claude/and/home/user/.claude.json. Claude Code sees valid, empty configuration. -
You configure Claude Code — install plugins, add MCP servers, change settings. All writes go directly to the PVC.
-
The second workspace starts. The same PVC mounts, and all configuration from the previous workspace is available.
For a comparison with other approaches, see Persist Claude Code configuration in Che workspaces.
-
An active
kubectlsession with permissions to create PVCs in your namespace. See Overview of kubectl. -
Claude Code installed in the workspace container image.
-
For concurrent workspaces: a storage class that supports
ReadWriteMany(RWX) access mode, such as AWS EFS or NFS. Standard block storage (gp2, gp3) supports onlyReadWriteOnce(RWO). -
All running workspaces must be stopped before creating the PVC. If a workspace is running when the PVC with the automount label is created,
/home/user/.claude.jsonmay be mounted as a directory instead of a file.
-
Create a file
claude-config-pvc.yamlwith the following PVC definition:kind: PersistentVolumeClaim apiVersion: v1 metadata: name: claude-config annotations: controller.devfile.io/mount-path: >- [{"path":"/home/user/.claude","subPath":".claude"}, {"path":"/home/user/.claude.json","subPath":".claude.json"}] labels: controller.devfile.io/mount-to-devworkspace: 'true' spec: accessModes: - ReadWriteMany resources: requests: storage: 1Gi -
Apply the PVC to your namespace:
$ kubectl apply -f claude-config-pvc.yaml -n <your_namespace>
-
Create the init pod to initialize the PVC.
The
/home/user/.claude.jsonsubPath target must exist as a file on the PVC before any workspace starts. Without this step, Kubernetes kubelet creates a directory instead of a file, and Claude Code fails to parse it.Create a file
claude-config-init-pod.yaml:apiVersion: v1 kind: Pod metadata: name: claude-config-init spec: restartPolicy: Never containers: - image: registry.access.redhat.com/ubi9/ubi-minimal name: init command: - sh - -c - | mkdir -p /mnt/.claude echo '{}' > /mnt/.claude.json echo "=== Initialization complete ===" ls -la /mnt/ volumeMounts: - mountPath: /mnt name: vol volumes: - name: vol persistentVolumeClaim: claimName: claude-config -
Apply the init pod:
$ kubectl apply -f claude-config-init-pod.yaml -n <your_namespace>
-
Wait for the pod to complete:
$ kubectl wait pod/claude-config-init --for=condition=Ready --timeout=120s
-
Verify the initialization:
$ kubectl logs claude-config-init
-
Delete the init pod:
$ kubectl delete pod claude-config-init
-
Start any workspace. The PVC auto-mounts into every workspace pod.
|
On multi-AZ clusters using |
-
Start a workspace and configure Claude Code (add an MCP server, install a plugin, or modify settings).
-
Stop and restart the workspace. Verify the configuration is preserved.
-
Start a different workspace. Verify the same configuration is available.
Filtering by workspace name
Control which workspaces mount the PVC by adding annotations:
annotations:
controller.devfile.io/mount-to-devworkspace-include: '<pattern>' (1)
controller.devfile.io/mount-to-devworkspace-exclude: '<pattern>' (2)
| 1 | Mount the PVC only to workspaces whose names match the pattern. |
| 2 | Mount the PVC to all workspaces except those whose names match the pattern. |
Supported patterns: exact match (name), prefix (name*), suffix (\*name), contains (\*name\*). Matching is on the DevWorkspace resource name.
Concurrent workspaces
| Access mode | Behavior |
|---|---|
ReadWriteOnce (RWO) |
One workspace at a time. Two workspaces on different nodes cause a multi-attach error. |
ReadWriteMany (RWX) |
Concurrent workspaces work. Requires a storage class that supports RWX, such as AWS EFS or NFS. Standard block storage (gp2, gp3) does not support RWX. |
Compatibility with persistUserHome
A dedicated PVC mounted at /home/user/.claude and the persistent home PVC mounted at /home/user/ coexist correctly as nested mounts. Writes to /home/user/.claude/ go to the dedicated PVC. Writes to other paths under /home/user/ go to the persistent home PVC.
If you only need persistence within a single workspace and not cross-workspace sharing, persistUserHome alone is sufficient.
Limitations
-
Requires manual PVC setup per user namespace.
-
RWX storage may not be available on all clusters.
-
On clusters with only block storage and multi-AZ topology, the init pod may cause scheduling failures. Use the tmp copy approach instead.