Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
21 commits
Select commit Hold shift + click to select a range
980f255
docs: add Cloud Access section covering tunnel setup and snap settings
kenvandine Apr 12, 2026
5582791
docs: note that ailab-cloud hub snap is fully self-contained
kenvandine Apr 12, 2026
6b67c37
feat(cloud): make port URLs tunnel-aware
kenvandine Apr 12, 2026
5315273
fix: import Request from fastapi in web/app.py
kenvandine Apr 12, 2026
31db68a
feat(cloud): implement tunnel client and snap wiring
kenvandine Apr 12, 2026
0c0b74e
fix(cloud): default to port 11500 when AILAB_CLOUD_PORTS not set
kenvandine Apr 12, 2026
2b8c5f3
fix(tunnel): use relative paths so the app works behind a sub-path proxy
kenvandine Apr 12, 2026
bd874f7
fix(tunnel): align WebSocket URL with hub's /d/{target}/{path} route
kenvandine Apr 12, 2026
94d93fa
fix(tunnel): pass gatewayUrl in hash so openclaw connects via tunnel
kenvandine Apr 12, 2026
0f9fcd4
fix(tunnel): whitelist hub origin in openclaw gateway allowedOrigins
kenvandine Apr 12, 2026
d0eccca
fix(tunnel): await origin whitelist before returning gateway URL
kenvandine Apr 12, 2026
116ab85
fix(tunnel): pass gateway token as Authorization Bearer on WS upgrade
kenvandine Apr 13, 2026
c2308ce
fix(openclaw): reset-failed before gateway restart; clamp contextWindow
kenvandine Apr 13, 2026
ae9e0fe
fix(tunnel): forward browser Origin header to local WS service
kenvandine Apr 13, 2026
b0b9bd5
fix(openclaw): patch openclaw.json as container user, not via push_file
kenvandine Apr 13, 2026
a1a18ee
Harden cloud tunnel registration
kenvandine Apr 13, 2026
c7228d4
Harden cloud reconnects and clean docs
kenvandine Apr 13, 2026
5a0fe2f
Use LXD socket for snap shells
kenvandine Apr 15, 2026
7763461
Fix snap shell exit handling
kenvandine Apr 15, 2026
ee095ab
Address PR review feedback
kenvandine Apr 15, 2026
5fa0c52
Update cloud docs for review
kenvandine Apr 15, 2026
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 6 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,12 @@ __pycache__/
dist/
build/
.pybuild/
.pytest_cache/
.ruff_cache/
.mypy_cache/
.coverage
.codex
=3.9.0
debian/.debhelper/
debian/ailab/
debian/ailab.postinst.debhelper
Expand Down
83 changes: 83 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -295,6 +295,89 @@ whose host port is already bound, so containers can start without conflicts.
Conflicting proxies are restored to the config so they activate once the port
is freed.

## Cloud Access

AI Lab Cloud lets you access your home containers from any browser, anywhere
— no VPN or port forwarding required. A lightweight tunnel client runs
alongside the web daemon, opening an outbound connection to a hub you
self-host on a VPS.

Keep `ailab` and `ailab-cloud` in step when deploying tunnel-related changes.
The client and hub are developed together, so protocol or registration changes
should be rolled out as a matched pair.

### How it works

```
Browser (anywhere) ──HTTPS──► AI Lab Cloud Hub (your VPS)
WebSocket tunnel
(outbound from home)
AI Lab (your home machine)
LXD proxy device
Container: openclaw / nullclaw / etc.
```

The hub authenticates your browser via GitHub OAuth and routes traffic only
to the tunnel registered by the matching GitHub user.

### Quick setup

**1. Deploy the hub** on a VPS with a single snap install — Redis, Caddy
(TLS), and the hub API are all bundled. Full instructions are in the
[AI Lab Cloud README](https://github.com/lemonade-sdk/ailab-cloud).

**2. Get your tunnel token.** Log in to your hub in a browser, then visit:
```
https://cloud.example.com/auth/tunnel-token
```

**3. Configure AI Lab on your home machine:**

```bash
sudo snap set ailab cloud.enabled=true
sudo snap set ailab cloud.host=https://cloud.example.com
sudo snap set ailab cloud.user=yourname
sudo snap set ailab cloud.token=<token from step 2>
sudo snap set ailab cloud.device-id=myhome # lowercase letters, digits, and hyphens only
sudo snap restart ailab.web
```

`cloud.host` accepts either `cloud.example.com` or `https://cloud.example.com`,
but the full URL is the recommended form.

**4. Visit** `https://myhome.cloud.example.com` from any browser and log
in with GitHub. The full AI Lab dashboard loads proxied through the tunnel,
including the interactive terminal and all "Open …" buttons for installed
tools.

### Cloud settings reference

| Setting | Description |
|---|---|
| `cloud.enabled` | Set to `true` to start the tunnel client (default: `false`) |
| `cloud.host` | Hub URL or hostname, e.g. `https://cloud.example.com` |
| `cloud.user` | Your GitHub username (must match your hub login) |
| `cloud.token` | Tunnel token from `/auth/tunnel-token` on the hub |
| `cloud.device-id` | Short identifier for this machine; use lowercase letters, digits, and hyphens only |

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fixed in 5fa0c52. I added cloud.ports to the Cloud settings table in README.md and documented the default behavior plus the common 18789 openclaw case.

| `cloud.ports` | Comma-separated local ports to expose through the tunnel (default: `11500`; add `18789` for openclaw and any other tool ports you want reachable remotely) |

```bash
snap get ailab cloud # view all cloud settings at once
```

Disable cloud access without losing the settings:

```bash
sudo snap set ailab cloud.enabled=false
sudo snap restart ailab.web
```

---

## Tips

**Web interface**: `ailab web` serves a React dashboard at
Expand Down
Loading