Skip to content

Quick Start ​

Docker Compose Deployment ​

Prerequisites ​

  • Linux host (Ubuntu 22.04+ / Debian 12+)
  • Docker Engine 28+, Docker Compose v2
  • At least one egress IP (proxy server)

1. Clone ​

bash
git clone https://github.com/ZaneL1u/cloud-cli-proxy.git
cd cloud-cli-proxy

2. Generate Environment Config ​

bash
bash deploy/scripts/setup-env.sh

The script supports two database modes:

  • SQLite single-file database: auto-created, zero config, managed by Docker Compose with /data persistence.

Both modes auto-generate an admin password (20 chars) and JWT secret (48 chars).

Important

The script displays the admin password once. Save it immediately.

3. Start Services ​

bash
# Start
docker compose pull
docker compose up -d

If prebuilt images are unavailable, build from source:

bash
docker compose -f docker-compose.yml -f docker-compose.build.yaml --profile build-only build --no-cache
docker compose -f docker-compose.yml -f docker-compose.build.yaml up -d --force-recreate

4. Verify ​

bash
curl http://127.0.0.1:8080/healthz
# {"status":"ok","checks":{"database":"ok","agent":"ok"}}

Service endpoints:

  • API: http://YOUR_HOST:8080
  • Admin dashboard (embedded): http://YOUR_HOST:8080
  • SSH proxy: YOUR_HOST:2222

Provisioning Users ​

Full workflow: login → add egress IP → create user → create host & bind → send connection command.

1. Get Admin Token ​

Log in via the admin dashboard or use the API:

bash
TOKEN=$(curl -s -X POST http://YOUR_HOST:8080/v1/auth/login \
  -H "Content-Type: application/json" \
  -d '{"username":"admin","password":"your-admin-password"}' | grep -o '"token":"[^"]*"' | cut -d'"' -f4)

2. Add Egress IP ​

Egress IPs use sing-box tun full-tunnel mode. Set tunnel_type to proxy and configure the upstream in proxy_config.

Supports 6 protocols: SOCKS5, VMess, VLESS, Shadowsocks, Trojan, HTTP.

bash
# Shadowsocks
curl -s -X POST http://YOUR_HOST:8080/v1/admin/egress-ips \
  -H "Authorization: Bearer $TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "label": "jp-ss-01",
    "ip_address": "198.51.100.5",
    "tunnel_type": "proxy",
    "provider": "manual",
    "proxy_config": {
      "type": "shadowsocks",
      "server": "198.51.100.5",
      "server_port": 8388,
      "method": "aes-256-gcm",
      "password": "your-ss-password"
    }
  }'
bash
# SOCKS5
curl -s -X POST http://YOUR_HOST:8080/v1/admin/egress-ips \
  -H "Authorization: Bearer $TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "label": "us-socks-01",
    "ip_address": "192.0.2.50",
    "tunnel_type": "proxy",
    "provider": "manual",
    "proxy_config": {
      "type": "socks",
      "server": "192.0.2.50",
      "server_port": 1080,
      "username": "user",
      "password": "pass"
    }
  }'

Test egress IP connectivity:

bash
curl -s -X POST http://YOUR_HOST:8080/v1/admin/egress-ips/{ipID}/test \
  -H "Authorization: Bearer $TOKEN"

The test result covers connectivity, exit IP match, and DNS leak detection.

3. Create User ​

bash
curl -s -X POST http://YOUR_HOST:8080/v1/admin/users \
  -H "Authorization: Bearer $TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "username": "zhangsan",
    "password": "initial-password-for-user",
    "expires_at": "2026-12-31T23:59:59Z"
  }'

4. Create Host & Bind Egress IP ​

bash
# Create host
curl -s -X POST http://YOUR_HOST:8080/v1/admin/hosts \
  -H "Authorization: Bearer $TOKEN" \
  -H "Content-Type: application/json" \
  -d '{"user_id": "user-uuid"}'

# Bind egress IP
curl -s -X POST http://YOUR_HOST:8080/v1/admin/bindings \
  -H "Authorization: Bearer $TOKEN" \
  -H "Content-Type: application/json" \
  -d '{"host_id": "host-uuid", "egress_ip_id": "egress-ip-uuid"}'

TIP

A host requires at least one bound egress IP to start.

5. Send Connection Info ​

After the host is created and the task shows the container is ready, copy the connection command from the host detail page in the admin dashboard.

Option A: curl + SSH

Send this command to the user (replace YOUR_HOST and SHORT_ID):

bash
curl -sSf http://YOUR_HOST/entry/SHORT_ID | bash

Or use the bootstrap flow (user enters their username):

bash
curl -sSf http://YOUR_HOST:8080/v1/bootstrap/script | bash

Option B: cloud-claude CLI (recommended)

In addition to the curl command above, share these three values:

FieldDescription
Gateway URLPublic HTTPS address of the control plane, e.g. https://gw.example.com
Short IDHost short ID from the host detail page
PasswordThe user's password set in the admin dashboard

After installing cloud-claude and running init with those values, the user runs cloud-claude from their project directory. The current directory is mounted at the same path inside the container via sshfs.

User Access ​

Install ​

Homebrew (macOS / Linux):

bash
brew tap ZaneL1u/tap
brew install cloud-claude

One-liner:

bash
curl -fsSL https://raw.githubusercontent.com/ZaneL1u/cloud-cli-proxy/main/scripts/install.sh | bash

Also available from Releases or go build ./cmd/cloud-claude.

First-time Setup ​

bash
cloud-claude init

Follow the prompts to enter gateway URL, Short ID, and password. Writes to ~/.cloud-claude/config.yaml.

Or use flags or environment variables:

bash
cloud-claude init --gateway https://gw.example.com --short-id abc123 --password your-password

export CLOUD_CLAUDE_GATEWAY=https://gw.example.com
export CLOUD_CLAUDE_SHORT_ID=abc123
export CLOUD_CLAUDE_PASSWORD=your-password
cloud-claude init

Daily Use ​

bash
cd ~/your-project
alias claude=cloud-claude

cloud-claude
cloud-claude -p "refactor this function"

Session management:

bash
cloud-claude                  # default: attach existing session
cloud-claude --new-session    # create a new isolated session
cloud-claude --take-over      # take over primary session, detach others
cloud-claude sessions         # list current sessions

Mount modes:

bash
cloud-claude --mount-mode=auto         # default: HotSync preferred, falls back to SSHFS
cloud-claude --mount-mode=full         # HotSync + SSHFS dual-track
cloud-claude --mount-mode=sshfs-only   # SSHFS only

Self-checks and troubleshooting:

bash
cloud-claude doctor                     # full five-domain check
cloud-claude doctor mount --fix         # mount check with auto-repair
cloud-claude explain MOUNT_SSHFS_DISCONNECTED  # error code lookup
cloud-claude env check                  # verify remote timezone, egress IP, FUSE, etc.

Common config (~/.cloud-claude/config.yaml):

  • proxy_commands — commands to run on the host (default ["git"]); set to [] to disable
  • hot_sync_max_file_mb — per-file throttling threshold (default 50MB)
  • CLOUD_CLAUDE_NO_PROMOTION=1 — disable cold-file read promotion

curl + SSH Access ​

Run the command your admin provided:

bash
curl -sSf http://YOUR_HOST/entry/abc123 | bash

Enter your password, wait for the container to be ready, and you will be connected via SSH automatically.

Pre-installed Tools ​

ToolDescription
Claude CodeRun claude in terminal
KasmVNC + ChromiumBrowser desktop via admin dashboard
Git / tmux / zshCommon dev tools
Node.jsJavaScript runtime

Using Claude Code ​

Once inside the container:

bash
claude

All Claude API requests are automatically routed through the egress IP. No proxy configuration needed.

Reconnecting ​

If SSH disconnects, re-run the same curl command to reconnect. The container keeps running.

Rebuilding ​

Click "Rebuild" in the admin dashboard to reset the environment. Home directory data is preserved.

Source Development ​

For contributing or customizing, set up a local dev environment as follows.

1. Install Dependencies ​

  • Go 1.25.7+
  • Node.js 20+ (recommend enabling corepack)
  • pnpm 10+
  • Docker Engine + Docker Compose v2
  • GNU Make

2. Set Up ​

bash
git clone https://github.com/ZaneL1u/cloud-cli-proxy.git
cd cloud-cli-proxy

make setup    # install frontend deps, generate .env
make dev      # backend + frontend hot reload

After startup:

  • Admin frontend: http://localhost:2568
  • Control Plane API: http://127.0.0.1:8080

3. Verify ​

bash
curl http://127.0.0.1:8080/healthz
make test

Common Commands ​

bash
make dev-api   # backend only
make dev-web   # frontend only
make help      # list all commands

Next Steps ​