Deploy OpenClaw Gateway on exe.dev VM with HTTPS Proxy
This page explains how to deploy an OpenClaw Gateway on an exe.dev virtual machine, accessible via HTTPS. It covers both automated install with Shelley and manual setup for remote access.
Read this when
- You want a cheap always-on Linux host for the Gateway
- You want remote Control UI access without running your own VPS
Goal: An OpenClaw Gateway deployed on an exe.dev virtual machine, accessible through https://<vm-name>.exe.xyz.
This procedure relies on exe.dev's standard exeuntu image. On other distributions, adapt the package names accordingly.
What you need
- An exe.dev account
ssh exe.devpermissions on exe.dev VMs (needed only for manual configuration)
Beginner quick path
- Go to https://exe.new/openclaw
- Provide your authentication key or token when requested
- Select "Agent" beside your VM and let Shelley finish provisioning
- Log into
https://<vm-name>.exe.xyz/using the shared secret you configured (token authentication is the default; password authentication also works after changinggateway.auth.mode) - Accept device pairing requests with
openclaw devices approve <requestId>
Automated install with Shelley
Shelley, the exe.dev agent, can deploy OpenClaw from a command line:
Set up OpenClaw (https://docs.openclaw.ai/install) on this VM. Use the non-interactive and accept-risk flags for openclaw onboarding. Add the supplied auth or token as needed. Configure nginx to forward from the default port 18789 to the root location on the default enabled site config, making sure to enable Websocket support. Pairing is done by "openclaw devices list" and "openclaw devices approve <request id>". Make sure the dashboard shows that OpenClaw's health is OK. exe.dev handles forwarding from port 8000 to port 80/443 and HTTPS for us, so the final "reachable" should be <vm-name>.exe.xyz, without port specification.
Manual installation
Create the VM
On your device:
ssh exe.dev new
Then establish the connection:
ssh <vm-name>.exe.xyz
Tip
Make sure this VM stays stateful. OpenClaw keeps
openclaw.json, per-agentauth-profiles.json, sessions, and channel or provider state inside~/.openclaw/, and the workspace inside~/.openclaw/workspace/.
Install prerequisites (on the VM)
sudo apt-get update
sudo apt-get install -y git curl jq ca-certificates openssl
Install OpenClaw
curl -fsSL https://openclaw.ai/install.sh | bash
Configure nginx to proxy to port 8000
Modify /etc/nginx/sites-enabled/default:
server {
listen 80 default_server;
listen [::]:80 default_server;
listen 8000;
listen [::]:8000;
server_name _;
location / {
proxy_pass http://127.0.0.1:18789;
proxy_http_version 1.1;
# WebSocket support
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
# Standard proxy headers
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $remote_addr;
proxy_set_header X-Forwarded-Proto $scheme;
# Timeout settings for long-lived connections
proxy_read_timeout 86400s;
proxy_send_timeout 86400s;
}
}
Replace forwarding headers rather than preserving client supplied chains. OpenClaw only trusts forwarded IP metadata from proxies that are explicitly configured, and append style X-Forwarded-For chains are considered a security weakness.
Access OpenClaw and approve devices
Open https://<vm-name>.exe.xyz/ (its address appears in the Control UI output during onboarding). If a login prompt appears, enter the shared secret from the VM.
Token authentication is the default in this guide, so fetch gateway.auth.token using openclaw config get gateway.auth.token, or create a new one with openclaw doctor --n. If the gateway uses password authentication instead, provide gateway.auth.password and OPENCLAW_GATEWAY_PASSWORD.
Approve devices through openclaw devices list and openclaw devices approve <requestId>. When unsure, use Shelley from your browser.
Remote channel setup
For remote hosts, prefer a single config patch call over multiple SSH calls to config set. Store real tokens in the VM environment or ~/.openclaw/.env, and place only SecretRefs in openclaw.json. The full SecretRef contract is documented at Secrets management.
On the VM, populate the service environment with the secrets it requires:
cat >> ~/.openclaw/.env <<'EOF'
SLACK_BOT_TOKEN=xoxb-...
SLACK_APP_TOKEN=xapp-...
DISCORD_BOT_TOKEN=...
OPENAI_API_KEY=sk-...
EOF
From your local machine, create a patch file and send it to the VM:
// openclaw.remote.patch.json5
{
secrets: {
providers: {
default: { source: "env" },
},
},
channels: {
slack: {
enabled: true,
mode: "socket",
botToken: { source: "env", provider: "default", id: "SLACK_BOT_TOKEN" },
appToken: { source: "env", provider: "default", id: "SLACK_APP_TOKEN" },
groupPolicy: "open",
requireMention: false,
},
discord: {
enabled: true,
token: { source: "env", provider: "default", id: "DISCORD_BOT_TOKEN" },
dmPolicy: "disabled",
dm: { enabled: false },
groupPolicy: "allowlist",
},
},
agents: {
defaults: {
model: { primary: "openai/gpt-5.6-sol" },
models: {
"openai/gpt-5.6-sol": { params: { fastMode: true } },
},
},
},
}
ssh <vm-name>.exe.xyz 'openclaw config patch --stdin --dry-run' < ./openclaw.remote.patch.json5
ssh <vm-name>.exe.xyz 'openclaw config patch --stdin' < ./openclaw.remote.patch.json5
ssh <vm-name>.exe.xyz 'openclaw gateway restart && openclaw health'
Use --replace-path when a nested allowlist should become exactly the patch value, for instance when replacing a Discord channel allowlist:
ssh <vm-name>.exe.xyz 'openclaw config patch --stdin --replace-path "channels.discord.guilds[\"123\"].channels"' < ./discord.patch.json5
Full channel configuration references are available at Discord and Slack.
Remote access
exe.dev manages authentication for remote access. By default, HTTP traffic on port 8000 is forwarded to https://<vm-name>.exe.xyz with email authentication.
Updating
openclaw update
For channel switches and manual recovery, see Updating.