Blog
Home

Running two Claude Code accounts side by side (personal + work)

17 September 2026 · 44 views

I use Claude Code for both personal projects and work, and wanted them fully separated: different subscriptions, no session conflicts, and no AI tool anywhere near secrets in a brownfield repo. This builds on my earlier post about getting Claude Code running in Docker in the first place. Here's how I set it up for two accounts.

Isolate via Docker

Rather than logging in and out, I run each account in its own container. Simplest setup: give each one its own directory, each with its own docker-compose.yml, container_name, and mount path pointing at the right project. Separate directories means no filename or project-name conflicts to think about. Each command just runs normally from within its own folder.

Logging in

Inside the new container, claude (or /login) triggers a fresh browser login, so pick the work account. Different container = different config, so no conflict with the personal session.

Gotcha: /login while already logged in sometimes reports success but keeps using the old account. If that happens: /logout, then /login again.

Secrets in a brownfield repo

Before mounting an older work project, I:

  1. Copied it to a new directory (no .git, so no history to worry about)
  2. Removed the obvious secrets in appsettings*.json
  3. Ran gitleaks anyway, and it found more secrets in a Debug directory that had been copied along with the project
  4. Cleaned those too, then git init fresh

Takeaway: don't trust a manual scrub. Run a real scanner, and check build/output folders, not just source.

Getting the commits back into the original repo

The copy started with git init, so any commits made there live in a brand new repo with its own root commit containing the entire codebase, an unrelated history to the original repo even though the code itself is identical. Don't PR that branch straight against master: it would compare against a completely different history, not just the real changes. Instead:

  1. Add the other repo as a temporary remote: git remote add other-repo /path/to/other/repo
  2. Fetch its history: git fetch other-repo
  3. Push the fetched branch to the original repo: git push origin other-repo/<branch>:<new-branch>
  4. Create a new branch off master in the original repo
  5. Cherry-pick the real commits onto it (skip the copy's own init commit): git cherry-pick <commit1> <commit2>
  6. Open the PR from this new branch against master

Remove the temporary remote once you're done (git remote remove other-repo).

If you keep both compose files in one directory

It's doable but more fiddly. With two files in the same folder, you need -f <filename> on every up/exec. And since Compose derives its project name from the directory by default, both stacks can end up sharing that name. Check with docker compose -f <file> ls, and add -p <name> if they match, or you may end up with the two stacks sharing a default network.

I found this out the hard way with something more than a network conflict. My config uses a named volume to persist the Claude Code login across restarts:

volumes:
  - type: volume
    source: claude-code-config
    target: /home/claude/.claude

volumes:
  claude-code-config:

With both compose files in the same directory, Compose prefixed claude-code-config with the same project name for both stacks, so they silently pointed at the same underlying volume. I logged into my work account in the second container, and my first container's login switched to the work account too.

Moving each setup into its own directory fixed it: Compose prefixes named volumes with the directory-derived project name automatically, so identical volume names in each file resolve to genuinely separate volumes. If you've already hit this, clean up the shared volume before starting fresh:

docker compose down -v
docker volume ls | grep claude-code-config
docker volume rm <leftover-volume-name>

Heads up: docker volume rm deletes the whole .claude state, not just the login: session history and any project memory go with it. If you want to keep that, back it up first:

docker run --rm -v claude-code-config:/data -v $(pwd):/backup busybox tar czf /backup/claude-config-backup.tar.gz /data

Separate directories avoids all of this from the start.

Quick reference

--build re-runs the Dockerfile, so you always get the latest Claude Code version rather than a cached one. --force-recreate makes sure the container itself is rebuilt from that fresh image.

Note: container_name must be unique across the whole host, not just within one Compose project. Separate directories don't get you out of this one, so give each container a distinct name.

# --- Personal account (ContainerA) ---
cd path/to/personal-project
docker compose up -d --build --force-recreate
docker compose exec ContainerA bash

# Inside the container: log in with the personal account
claude
/login

# --- Work account (ContainerB) ---
cd path/to/work-project
docker compose up -d --build --force-recreate
docker compose exec ContainerB bash

# Inside the container: log in with the work account
claude
/login

# If a container is stuck on the wrong account:
/logout
/login
# Checking for a project-name / volume collision (only relevant if you
# end up with two compose files in the same directory)
docker compose -f docker-compose.yml ls
docker compose -f docker-compose-work.yml ls
docker volume ls | grep claude-code-config

# Cleaning up a shared/stale volume before starting fresh
docker compose down -v
docker volume rm <leftover-volume-name>

# Brownfield secrets check before mounting a project
cp -r original-project/ copy-project/
rm -rf copy-project/.git
gitleaks detect --source copy-project/
git -C copy-project init

# Getting commits made in the copy back into the original repo
git remote add other-repo /path/to/other/repo
git fetch other-repo
git push origin other-repo/<branch>:<new-branch>
git checkout -b <new-branch> master
git cherry-pick <commit1> <commit2>
git remote remove other-repo

Co-authored with Claude.

Comments

← All articlesView as Markdown