This project provides a fully configurable Docker setup to run Claude Code with Remote Control enabled on a Virtual Private Server (VPS). It includes transparent GitHub authentication, Git identity mapping, and automated session backups.
-
Multi-Session Web Manager: A beautiful, responsive glassmorphic dark-mode web portal to create, start, stop, and destroy sibling Claude Code container sessions on-demand.
-
GitHub OAuth & ACL Security: Exposes the web manager securely behind a single-button "Sign In with GitHub" login flow, restricting access to whitelisted accounts specified in
ALLOWED_GITHUB_USERS. -
Automatic HTTPS reverse proxy: Includes Caddy to automatically provision Let's Encrypt SSL certificates and proxy incoming traffic on ports 80/443 directly to the web portal.
-
Sandboxed Workspaces (Volumes): Each session is allocated an isolated Docker volume for its workspace, cloned automatically from GitHub on startup. Deleting a session gives you the option to wipe the volume to conserve space.
-
VPS-Ready: Easily host your Claude Code agent on any Linux VPS.
-
Secure GitHub Auth: Uses a GitHub Personal Access Token to authenticate all git clone/push/pull commands without exposing SSH keys inside the container.
-
Dockerized Sandbox: Runs in an isolated Docker container with essential tools (
git,curl,ghCLI). -
Auto Mode Integration: Configured to run in Claude's Auto Mode (
--permission-mode auto) by default, utilizing an AI safety classifier to auto-approve safe tasks and eliminate prompt fatigue. -
User Identity Adapter: Dynamically maps the running container user (UID/GID) to match your host system user. This prevents files created by the agent inside the shared
/workspacefrom being owned byrooton the host. -
Session & Connection Persistence: Configures a persistent session name (defaults to the repository name) and an optional unique static UUID, allowing your Remote Control session connection to persist across container re-creations without re-pairing.
-
Interactive Config-Backed Setup: A clean configuration setup (
setup.sh+config.js) verifies host paths, writes to a schema-validatedconfig.json, and compiles variables to.envautomatically. -
Auto-Restore Session: Restores the Claude authentication state from the host machine backups (
.claude.json) if it gets lost during container recreation.
Ensure the following tools are installed and configured on your VPS host machine:
- Docker and Docker Compose
- Git
- Claude Code CLI (
@anthropic-ai/claude-code): Before running the sandbox, you must install the Claude Code client on your VPS host and authenticate (by runningclaudeand completing the login process) under the same user account that will execute the container. The Docker setup mounts and reads the session configuration (including~/.claude.json) directly from this user's home directory. - A GitHub OAuth Application:
- To enable "Sign In with GitHub", you must register an OAuth application on your GitHub developer settings page: GitHub OAuth Apps.
- Configure the application:
- Homepage URL:
https://<your-vps-domain>(orhttp://localhost:4000for local test) - Authorization callback URL:
https://<your-vps-domain>/api/auth/github/callback(orhttp://localhost:4000/api/auth/github/callbackfor local test)
- Homepage URL:
- Copy the generated Client ID and Client Secret keys to use during the configuration wizard.
- A GitHub Personal Access Token (PAT) (optional fallback for non-OAuth listings/manual overrides).
Choose one of the following methods to deploy the codebase to your VPS:
If you have Git installed on your VPS, clone the repository directly:
git clone https://github.com/sgomez/cc-remote.git
cd cc-remoteIf you do not want to configure Git on your VPS, download and extract the ZIP archive:
curl -L -o cc-remote.zip https://github.com/sgomez/cc-remote/archive/refs/heads/main.zip
unzip cc-remote.zip
cd cc-remote-mainWhen a new version is released, you can overwrite the previous one while preserving your settings (config.json and .env, which are ignored by Git and not part of the source):
-
If you cloned via Git:
git pull docker compose down docker compose up -d --build
-
If you downloaded via ZIP:
# Download the latest archive curl -L -o cc-remote-new.zip https://github.com/sgomez/cc-remote/archive/refs/heads/main.zip # Extract and overwrite the files (unzip -o overwrites existing files without prompting) unzip -o cc-remote-new.zip rm cc-remote-new.zip # Rebuild and restart the container docker compose down docker compose up -d --build
Run the interactive setup script:
./setup.shThis script runs the interactive setup wizard (config.js) inside a temporary Node Docker container to query your VPS settings, validate paths, generate a schema-validated config.json, and compile the .env file automatically.
During setup, you will be prompted for:
- Your GitHub Personal Access Token (Optional fallback to set name/email).
- Your VPS Domain Name (e.g.,
cc.example.com). - Your GitHub OAuth Client ID.
- Your GitHub OAuth Client Secret.
- Whitelisted GitHub usernames (
ALLOWED_GITHUB_USERS, comma-separated) allowed to access the system (e.g.sgomez). - The script automatically outputs a link and a step-by-step console guide to register the GitHub OAuth Application correctly based on the domain you enter.
- Paths for the project directory, Claude configuration directory (
~/.claude), and session credentials file (~/.claude.json) are resolved automatically. - Whether to enable the Caddy reverse proxy, and specify custom HTTP/HTTPS port mappings (HTTP can be disabled with port
0).
If you did not opt to launch the container automatically at the end of setup.sh, you can build and start it manually:
docker compose up -d --buildIf you followed the prerequisites and logged in to Claude on your VPS host (claude or claude login), your authentication state (~/.claude.json) is mounted automatically, and the agent will start authenticated.
Otherwise, if you need to authenticate inside the container, view the container logs to find the authentication URL:
docker compose logs -fClick the provided URL, sign in with your Anthropic account, copy the authentication token, and execute it into the container (if the remote control asks for it), or ensure your host configuration (~/.claude.json) is correctly populated under the same user running the docker commands.
The project features a built-in web management interface (web-manager service) proxy-routed securely behind Caddy. It allows you to dynamically spin up, start, stop, and destroy Claude Code container sessions from your browser. Each session gets its own isolated Docker volume and workspace sandbox.
- Open your browser and navigate to
https://<your-vps-domain>(orhttp://localhost:4000for local test environments). - Click Sign In with GitHub.
- Authorize the application. The backend will verify if your GitHub username is configured in the whitelisted
ALLOWED_GITHUB_USERSenvironment variable. If so, a secure signed session cookie is created.
To avoid heavy nesting, performance hits, and security vulnerabilities associated with Docker-in-Docker (DinD), this project uses a Sibling Containers architecture:
- The
web-managercontainer mounts the host's/var/run/docker.sock. - When you click "Launch Container", the web manager calls the Docker API to create and start a sibling container running the
cc-remote-claude-agentimage. - Claude credentials (
~/.claude.jsonand~/.claude) are safely mounted from the host, allowing all dynamically spawned containers to share the same authentication state.
- Isolation: Each container session runs in isolation, mounting a dedicated Docker volume named
cc-remote-workspace-<session_name>. - Auto-Cloning: The entrypoint script automatically clones the specified GitHub repository into the empty volume on container startup.
- Teardown: When you delete a session from the web dashboard, you are prompted with a checkbox to also delete the associated workspace volume. Keeping the volume unchecked preserves the code state for future runs.
- Dynamic GitHub Authentication: The OAuth token obtained during your login is dynamically injected as the
GITHUB_TOKENenvironment variable in the dynamically generated Claude Code session containers, allowing seamless access to clone, fetch, and pull all repositories (personal and organizational) you have access to in your account.
| Action | Command |
|---|---|
| Start in background | docker compose up -d |
| Stop container | docker compose down |
| View logs | docker compose logs -f |
| Rebuild container | docker compose build --no-cache |
| Open container terminal | docker compose exec claude-agent bash |
By default, the container runs Claude Code in Auto Mode (--permission-mode auto).
Auto Mode replaces routine permission prompts with a background safety classifier. This classifier evaluates pending tool actions and automatically approves safe operations (like reading or editing files in the workspace and running standard git operations) while blocking actions that appear destructive, irreversible, or outside the scope of your request. This significantly reduces "approval fatigue" during remote control sessions.
Because the Claude Code agent runs entirely inside an isolated Docker container, the container acts as a secure sandbox. Any filesystem changes, commands, or tool executions occur within this sandbox and cannot access or modify the host VPS system files or configurations directly. This sandboxed architecture makes running in Auto Mode highly secure and safe.
You can customize the classifier's behavior (e.g. telling it which repositories, buckets, or domains are trusted to avoid false-positive blocks on routine tasks) by defining an autoMode settings block in your user configuration.
Since the container automatically mounts your host's Claude credentials file (CLAUDE_JSON_PATH which defaults to ~/.claude.json), you can customize the configuration directly in ~/.claude.json on the host:
{
"permissions": {
"defaultMode": "auto"
},
"autoMode": {
"environment": [
"$defaults",
"Source control: github.com/your-org and all repos under it",
"Trusted internal domains: *.internal.example.com"
]
}
}You can change the permission mode to other values (e.g., default, acceptEdits, plan, dontAsk, or bypassPermissions if you want to bypass prompts entirely in your sandbox) by setting the PERMISSION_MODE environment variable in your .env or during the interactive ./setup.sh configuration.
For custom agent instructions, workflows, or rules (such as TDD guidelines, code style rules, or custom skills) to be loaded and used by the agent inside the container, they must be located inside the project repository under the .agents/ folder.
Since the container mounts your project repository to /workspace, the agent will automatically discover, load, and follow these rules and skills when it initializes.