# claudaris Claudaris (klaw-DAR-iss): A moveable docker container for Claude code. using Arch btw. Full documentation lives in [`docs/`](docs/README.md): [getting started](docs/getting-started.md), the [`claudaris` executable](docs/claudaris.md), and [MCP servers](docs/mcp.md). ## Configure Run the interactive wizard and answer its prompts (press enter to keep a default): ``` ./claudaris config ``` It writes `NAME`, `DATA_DIR`, and `WORKSPACE_DIR` to `.env` (gitignored — every user keeps their own), which every other command sources. `NAME` should be something unique to you (e.g. `claude-ten`) if more than one person is running a container from this same repo checkout. `DATA_DIR` defaults to `/data/$NAME`; `WORKSPACE_DIR` (the host dir mounted as `/projects` in the container) defaults to `/home/$USER/projects`. `config`/`configure` can be re-run any time to update `.env`. ## Build container As root run build (always `--no-cache --pull`, so it picks up the latest Claude Code release): ``` sudo ./claudaris build ``` ## Start the container Make sure the volumes are as you like and start the container. ``` sudo ./claudaris start ``` ## Connect to the container ``` sudo ./claudaris connect ``` ## Stop and remove the container ``` sudo ./claudaris remove ``` (aliases: `stop`, `rm`) ## Optional: SSH access to other nodes To let the container SSH out to other machines, create `$DATA_DIR/ssh` on the host and populate it with keys/config *before* running `./claudaris start`. If present, it's bind-mounted read-only to `/root/.ssh`. It's off by default. ## MCP servers MCP servers for [Gitea](https://gitea.com/gitea/gitea-mcp), [n8n](https://github.com/czlonkowski/n8n-mcp), and [InvokeAI](https://github.com/coinstax/invokeai-mcp-server) are baked into the image and registered with Claude Code (user scope) automatically on container start. To point them at your instances, uncomment and fill in the `export` lines at the bottom of your host-persisted `$DATA_DIR/home/bash_aliases` (`GITEA_HOST`, `GITEA_ACCESS_TOKEN`, `N8N_API_URL`, `N8N_API_KEY`, `INVOKEAI_BASE_URL`) — if yours was seeded before this feature existed, copy the block from `files/bash_aliases`. Tokens stay on the host, out of the image and repo. Note the services run elsewhere (not in this container), so use URLs reachable from inside it — `127.0.0.1` here means the container itself. ## Notes Claude Code is installed at build time under `/root`, so a rebuild always picks up the latest release. Two files are bind-mounted individually to survive that: `~/.claude/.credentials.json` (the OAuth token) and `~/.claude.json` (account/onboarding state — Claude Code checks this too, so persisting the token alone isn't enough to avoid a re-login prompt after a rebuild). `./claudaris start` seeds both from empty on the host the first time it runs. Logging in once then survives rebuilds without carrying the CLI binary or the rest of `~/.claude` (settings, history, projects, caches) along with it. The container also stops itself once its tmux session ends (any shell exit — Ctrl+D, `exit`, crash) instead of running forever, and there's no Docker restart policy — `./claudaris connect` and `./claudaris start` both bring it back up automatically if you find it stopped. `.bashrc` and `bash_aliases` are both bind-mounted as single files so they can be tweaked per-host (e.g. a coworker importing their own aliases) without a rebuild. `./claudaris start` seeds them into `$DATA_DIR/home/.bashrc` and `$DATA_DIR/home/bash_aliases` from `files/bashrc` and `files/bash_aliases` the first time it runs, without overwriting later edits. Anything that needs to survive regardless (PATH, zoxide, git identity) lives in `/etc/...` inside the image instead of under `/root`. The container is started with `--hostname "$NAME"`, so the prompt reads `root@claudaris` (or whatever you set `NAME` to via `./claudaris config`) instead of a random container ID.