Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions modules/end-user-guide/nav.adoc
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,11 @@
* xref:using-ai-assistants-in-workspaces.adoc[]
** xref:configuring-an-ai-provider-api-key.adoc[]
** xref:changing-the-ai-tool-on-a-workspace.adoc[]
** xref:persist-claude-code-configuration.adoc[]
*** xref:share-claude-code-configuration-with-pvc-direct-mount.adoc[]
*** xref:share-claude-code-configuration-with-pvc-tmp-copy.adoc[]
*** xref:share-claude-code-configuration-with-gitops.adoc[]
*** xref:troubleshoot-claude-code-configuration-persistence.adoc[]
* xref:using-credentials-and-configurations-in-workspaces.adoc[]
** xref:mounting-secrets.adoc[]
*** xref:creating-image-pull-secrets.adoc[]
Expand Down
110 changes: 110 additions & 0 deletions modules/end-user-guide/pages/persist-claude-code-configuration.adoc
Original file line number Diff line number Diff line change
@@ -0,0 +1,110 @@
:_content-type: CONCEPT
:description: Persist and share Claude Code configuration across {prod-short} workspaces.
:keywords: user-guide, claude-code, ai, configuration, persistence, pvc
:navtitle: Persist Claude Code configuration
:page-aliases: persisting-claude-code-configuration.adoc

[id="persist-claude-code-configuration"]
= Persist Claude Code configuration in {prod-short} workspaces

To reuse Claude Code skills, settings, MCP servers, and plugins across {prod-short} workspaces, persist the configuration in a shared volume or a Git repository. Without persistence, each new workspace requires a fresh setup.

== Claude Code configuration files

Claude Code stores configuration in two separate locations in the user's home directory:

|===
| Path | Contents

| `{prod-home}/.claude/`
| Settings, plugins, custom agents, hooks, per-project memory.

| `{prod-home}/.claude.json`
| Application settings and MCP server configurations.
|===

[IMPORTANT]
====
MCP server configurations are stored in `{prod-home}/.claude.json`, a separate file at the home directory root, not inside `{prod-home}/.claude/`. Both locations must be persisted.

Claude Code writes runtime state to both paths during every session, including session files, caches, and usage statistics. These paths must be writable. Mounting a read-only ConfigMap or Secret directly to these paths causes Claude Code to fail.
====

== Available approaches

|===
| Approach | Summary

| xref:share-claude-code-configuration-with-pvc-direct-mount.adoc[]
| Both `{prod-home}/.claude/` and `{prod-home}/.claude.json` are mounted directly from a dedicated PVC. All changes persist automatically. Requires a one-time init pod to pre-create `.claude.json`.

| xref:share-claude-code-configuration-with-pvc-tmp-copy.adoc[]
| A dedicated PVC is mounted at `/tmp/claude`. A `postStart` command copies everything into the home directory. No init pod is required, but changes must be synced back manually before stopping the workspace.

| xref:share-claude-code-configuration-with-gitops.adoc[]
| A Git repository stores the baseline Claude Code configuration. The {devworkspace} Operator clones the repository at startup, and a `postStart` command copies the configuration into the home directory.
|===

== Claude Code file reference

|===
| Path | Purpose | Size | Regeneratable

| `{prod-home}/.claude/settings.json`
| Permissions, hooks, enabled plugins, model preferences.
| Small
| No

| `{prod-home}/.claude/settings.local.json`
| Local setting overrides.
| Small
| No

| `{prod-home}/.claude/CLAUDE.md`
| User-level instructions for Claude.
| Small
| No

| `{prod-home}/.claude/plugins/`
| Installed plugins and caches.
| Large (100{nbsp}MB+)
| Partially

| `{prod-home}/.claude/agents/`
| Custom agent definitions.
| Small
| No

| `{prod-home}/.claude/hooks/`
| Shell scripts for session lifecycle.
| Small
| No

| `{prod-home}/.claude/projects/`
| Per-project memory and settings.
| Medium
| No

| `{prod-home}/.claude.json`
| Application settings and MCP server configurations.
| Small
| No

| `{prod-home}/.claude/history.jsonl`
| Conversation history.
| Large
| Optional

| `{prod-home}/.claude/plugins/cache/`
| Plugin download cache.
| Large
| Yes
|===

.Additional resources

* xref:share-claude-code-configuration-with-pvc-direct-mount.adoc[]
Comment thread
tolusha marked this conversation as resolved.
* xref:share-claude-code-configuration-with-pvc-tmp-copy.adoc[]
* xref:share-claude-code-configuration-with-gitops.adoc[]
* xref:troubleshoot-claude-code-configuration-persistence.adoc[]
* link:https://github.com/devfile/devworkspace-operator/blob/main/docs/additional-configuration.adoc#automatically-mounting-volumes-configmaps-and-secrets[Automatically mounting volumes, configmaps, and secrets]
Original file line number Diff line number Diff line change
@@ -0,0 +1,117 @@
:_content-type: PROCEDURE
:description: Share Claude Code configuration across {prod-short} workspaces by storing it in a Git repository.
:keywords: user-guide, claude-code, ai, configuration, persistence, gitops, git
:navtitle: Share configuration with GitOps
:page-aliases: sharing-claude-code-configuration-with-gitops.adoc

[id="share-claude-code-configuration-with-gitops"]
= Share Claude Code configuration across workspaces with GitOps

Instead of using a shared PVC, you can store Claude Code configuration in a Git repository and pull it into workspaces at startup. Each workspace gets its own isolated, writable copy of the configuration.

This approach eliminates multi-attach errors and last-write-wins data corruption risks that can occur with shared PVCs on clusters without RWX storage.

== How it works

A central Git repository stores the baseline Claude Code configuration. The repository is listed in the `projects` section of the devfile, and the {devworkspace} Operator's project-clone init container clones it automatically at workspace startup. A `postStart` command then copies the configuration files from the cloned repository into the home directory.

Two usage patterns are possible:

* *Read-only baseline* — administrators maintain a shared repository with team-wide settings such as security hooks, API proxies, and approved plugins. The configuration is cloned at startup and copied into the home directory. Developers do not push changes back. This is suitable for enforcing organization-wide policies.

* *User-specific persistence* — each developer maintains a private branch or repository with personal configuration. The repository is cloned at startup and copied into the home directory. Optionally, a `preStop` command or manual step commits and pushes changes back before the workspace stops.

For a comparison with other approaches, see xref:persist-claude-code-configuration.adoc[].

.Prerequisites

* An active `{orch-cli}` session with permissions to create resources in your {orch-namespace}. See {orch-cli-link}.

* Claude Code installed in the workspace container image.

* A Git repository containing Claude Code configuration files. The repository must be accessible from the workspace. At minimum, the repository should contain:
+
----
.claude/
settings.json
CLAUDE.md
.claude.json
----

* Git credentials configured in the workspace if the repository is private. See xref:authenticating-to-a-git-server-from-a-workspace.adoc[].

.Procedure

. Add the configuration repository to the `projects` section of your devfile:
+
====
[source,yaml,subs="+quotes,+attributes"]
----
projects:
- name: claude-config
git:
remotes:
origin: '__<git_repository_url>__' # <1>
----
<1> Replace with the URL of your Claude Code configuration repository.
====

. Add a `postStart` command to copy the configuration from the cloned repository into the home directory:
+
====
[source,yaml,subs="+quotes,+attributes"]
----
commands:
- id: init-claude-config
exec:
commandLine: |
cp -a /projects/claude-config/.claude/. {prod-home}/.claude/ 2>/dev/null || true
cp /projects/claude-config/.claude.json {prod-home}/.claude.json 2>/dev/null || true
component: __<editor_container>__ # <1>
events:
postStart:
- init-claude-config
----
<1> Replace with the name of your editor container component in the devfile.
====

. Start the workspace.

. Optional: To persist changes back to the Git repository before stopping, commit and push from within the workspace:
+
[subs="+quotes,+attributes"]
----
$ cp -a {prod-home}/.claude/. /projects/claude-config/.claude/
$ cp {prod-home}/.claude.json /projects/claude-config/.claude.json
$ cd /projects/claude-config
$ git add -A && git commit -m "Update Claude Code configuration" && git push
----

.Verification

. Start a workspace with the devfile containing the configuration repository.
. Verify Claude Code starts with the expected configuration (settings, MCP servers, plugins).
. Make a configuration change, sync back to the repository, and push.
. Start a new workspace with the same devfile. Verify the updated configuration is available.

== Advantages

* No RWX storage requirement. Each workspace uses its own local storage.
* No multi-attach errors. Concurrent workspaces are not affected.
* Git history provides an audit trail of configuration changes.
* Works across clusters and {prod-short} instances.

== Limitations

* Requires a Git repository accessible from the workspace.
* Changes must be committed and pushed to persist. Unsaved changes are lost when the workspace stops.
* Large files such as plugin caches (`{prod-home}/.claude/plugins/cache/`) are not suitable for Git storage. Consider adding them to `.gitignore`.
* Merge conflicts can occur when multiple workspaces push changes to the same branch concurrently.

.Additional resources

* xref:persist-claude-code-configuration.adoc[]
* xref:share-claude-code-configuration-with-pvc-direct-mount.adoc[]
* xref:share-claude-code-configuration-with-pvc-tmp-copy.adoc[]
* xref:troubleshoot-claude-code-configuration-persistence.adoc[]
* xref:authenticating-to-a-git-server-from-a-workspace.adoc[]
Loading
Loading