# The `claudaris` executable `./claudaris` is a single bash script at the repo root that wraps `docker compose` (see `docker-compose.yml`). It `cd`s to its own directory first, so it can be invoked from anywhere. Run it with no arguments (or `help`) for usage. Plain `docker compose` subcommands work directly too, as long as `.env` is present (compose reads it automatically) — `claudaris` just adds the `config` wizard and the host-side seeding/mount logic below. ``` Usage: ./claudaris Commands: config, configure Interactive wizard to write .env with your settings build Build the container image (always --no-cache --pull) start Start (or create) the container connect Start the container if needed, then attach a tmux session remove, stop, rm Stop and remove the container help Show this message ``` All commands source `.env` if present (gitignored, written by `config`), falling back to `NAME=claudaris` and the defaults listed below. ## `config` (alias: `configure`) Interactive wizard: prompts for `NAME`, `DATA_DIR`, and `WORKSPACE_DIR`, showing the current/default value for each (enter keeps it), then writes all three to `.env`. Safe to re-run any time. See [Getting started](getting-started.md#1-configure) for what each variable means. ## `build` ```bash sudo ./claudaris build ``` Runs `docker compose build --no-cache --pull`. Always uncached so a rebuild picks up the latest Arch packages, the latest Claude Code release (installed straight into `/root` in the image), and the latest [MCP server](mcp.md) releases. ## `start` Runs `docker compose up -d`, which creates the container if it doesn't exist and (re)starts it otherwise, per `docker-compose.yml`. Container/image name, volumes, and workspace mount come from `NAME`/`DATA_DIR`/`WORKSPACE_DIR`, which compose reads from `.env` the same way `claudaris` does — mount changes in `docker-compose.yml` take effect on the next `up -d` without needing `remove` first. Before calling compose, `start` seeds the host side, without overwriting anything that already exists: - `$DATA_DIR/home/.bashrc` and `$DATA_DIR/home/bash_aliases` — copied from `files/bashrc` and `files/bash_aliases`. - `$DATA_DIR/claude/credentials.json`, `$DATA_DIR/claude/claude.json`, and `$DATA_DIR/opencode/auth.json` — created empty. Seeding them as files matters: if Docker had to create the mount targets itself it would make directories, breaking the login mounts. - `docker-compose.override.yml` (gitignored) — written to add the SSH mount below if `$DATA_DIR/ssh` exists, removed otherwise. Compose merges this file automatically when present; it's the only mount that can't live in `docker-compose.yml` directly, since compose has no way to make a volume conditional on a host path existing. The mounts, all declared in `docker-compose.yml`: | Mount | Purpose | | --- | --- | | `hostname: ${NAME}` | Prompt reads `root@$NAME` instead of a random container ID. | | `$DATA_DIR/home/.bashrc` → `/root/.bashrc` | Per-host shell config, editable without a rebuild. | | `$DATA_DIR/home/bash_aliases` → `/opt/dotfiles/bash_aliases` | Per-host aliases and [MCP env vars](mcp.md); sourced by `.bashrc`. | | `$DATA_DIR/claude/credentials.json` → `/root/.claude/.credentials.json` | Claude Code OAuth token. | | `$DATA_DIR/claude/claude.json` → `/root/.claude.json` | Claude Code account/onboarding state and user-scope MCP config. | | `$DATA_DIR/opencode/auth.json` → `/root/.local/share/opencode/auth.json` | OpenCode provider credentials (API keys/OAuth tokens). | | `$WORKSPACE_DIR` → `/projects` | Your project workspace. | | `$DATA_DIR/ssh` → `/root/.ssh` (read-only, override file, only if the host dir exists) | Opt-in SSH access to other machines. | The login files are individual file mounts rather than a directory volume on purpose: both Claude Code and OpenCode likely save them atomically (write a temp file, then `rename()` over the target), and `rename()` onto a symlink replaces the symlink instead of writing through it — which would silently break persistence. A bind mount doesn't have that failure mode. ## `connect` ```bash sudo ./claudaris connect ``` Runs `docker compose up -d` (a no-op if already running) and then `docker compose exec claudaris bash`. The explicit `up -d` matters because the container stops itself: the entrypoint creates the `main` tmux session and exits once that session ends (tmux defaults — a window closes when its shell exits, the session closes with its last window). There's no `--restart` policy, so after a Ctrl+D the container sits stopped until `connect` (or `start`) brings it back. `tmux` itself stays installed and available — run it manually inside the container (the in-container `tmux` wrapper attaches to the `main` session if it exists and creates it otherwise) if you want it. ## `remove` (aliases: `stop`, `rm`) Runs `docker compose down`, stopping and removing the container so the next `start` recreates it fresh — needed after a `build` to actually run the new image, or after changing mounts. Nothing under `$DATA_DIR` or `$WORKSPACE_DIR` is touched.