fix: resolve open docker and gateway-optional regressions (#291)
This commit is contained in:
parent
44aaf150c2
commit
a18240381c
|
|
@ -6,4 +6,5 @@ node_modules
|
|||
*.md
|
||||
.github
|
||||
ops
|
||||
scripts
|
||||
scripts/*
|
||||
!scripts/check-node-version.mjs
|
||||
|
|
|
|||
|
|
@ -71,6 +71,9 @@ NEXT_PUBLIC_GATEWAY_URL=
|
|||
# Keep gateway auth secrets server-side only (OPENCLAW_GATEWAY_TOKEN / GATEWAY_TOKEN).
|
||||
# Gateway client id used in websocket handshake (role=operator UI client).
|
||||
NEXT_PUBLIC_GATEWAY_CLIENT_ID=openclaw-control-ui
|
||||
# Gateway optional mode: set to 'true' if deploying on VPS with firewall blocking WebSocket ports.
|
||||
# In optional mode, Mission Control runs standalone; core CRUD features work but live gateway events do not.
|
||||
# NEXT_PUBLIC_GATEWAY_OPTIONAL=false
|
||||
|
||||
# === Data Paths (all optional, defaults to .data/ in project root) ===
|
||||
# MISSION_CONTROL_DATA_DIR=.data
|
||||
|
|
|
|||
26
README.md
26
README.md
|
|
@ -73,6 +73,32 @@ pnpm dev # http://localhost:3000
|
|||
Initial login is seeded from `AUTH_USER` / `AUTH_PASS` on first run.
|
||||
If `AUTH_PASS` contains `#`, quote it (e.g. `AUTH_PASS="my#password"`) or use `AUTH_PASS_B64`.
|
||||
|
||||
## Gateway Optional Mode (Standalone Deployment)
|
||||
|
||||
Mission Control can run in standalone mode without a gateway connection. This is useful when:
|
||||
|
||||
- Deploying on a VPS with firewall rules blocking non-standard WebSocket ports (18789/18790)
|
||||
- Testing UI/core workflows without a running gateway
|
||||
- Running Mission Control primarily for project/task operations
|
||||
|
||||
Enable with:
|
||||
|
||||
```bash
|
||||
NEXT_PUBLIC_GATEWAY_OPTIONAL=true
|
||||
```
|
||||
|
||||
When enabled, the HUD status shows `Gateway Optional (Standalone)` instead of `Disconnected`.
|
||||
|
||||
Works without gateway:
|
||||
- Task board, projects, agents, sessions, scheduler, webhooks, alerts, activity/audit, cost tracking
|
||||
|
||||
Requires active gateway:
|
||||
- Real-time session updates
|
||||
- Agent-to-agent messaging
|
||||
- Gateway log streaming
|
||||
|
||||
For production VPS setups, you can also proxy gateway WebSockets over 443. See `docs/deployment.md`.
|
||||
|
||||
### Docker Hardening (Production)
|
||||
|
||||
For production deployments, use the hardened compose overlay:
|
||||
|
|
|
|||
|
|
@ -21,12 +21,12 @@ services:
|
|||
- NET_BIND_SERVICE
|
||||
security_opt:
|
||||
- no-new-privileges:true
|
||||
pids_limit: 256
|
||||
deploy:
|
||||
resources:
|
||||
limits:
|
||||
memory: 512M
|
||||
cpus: '1.0'
|
||||
pids: 256
|
||||
networks:
|
||||
- mc-net
|
||||
restart: unless-stopped
|
||||
|
|
|
|||
|
|
@ -175,3 +175,36 @@ Then restart the gateway and reconnect from Mission Control.
|
|||
|
||||
Device identity signing uses WebCrypto and requires a secure browser context.
|
||||
Open Mission Control over HTTPS (or localhost), then reconnect.
|
||||
|
||||
### "Gateway shows offline on VPS deployment"
|
||||
|
||||
Browser WebSocket connections to non-standard ports (like 18789/18790) are often blocked by VPS firewall/provider rules.
|
||||
|
||||
Quick option:
|
||||
|
||||
```bash
|
||||
NEXT_PUBLIC_GATEWAY_OPTIONAL=true
|
||||
```
|
||||
|
||||
This runs Mission Control in standalone mode (core features available, live gateway streams unavailable).
|
||||
|
||||
Production option: reverse-proxy gateway WebSocket over 443.
|
||||
|
||||
nginx example:
|
||||
|
||||
```nginx
|
||||
location /gateway-ws {
|
||||
proxy_pass http://127.0.0.1:18789;
|
||||
proxy_http_version 1.1;
|
||||
proxy_set_header Upgrade $http_upgrade;
|
||||
proxy_set_header Connection "upgrade";
|
||||
proxy_set_header Host $host;
|
||||
proxy_read_timeout 86400;
|
||||
}
|
||||
```
|
||||
|
||||
Then point UI to:
|
||||
|
||||
```bash
|
||||
NEXT_PUBLIC_GATEWAY_URL=wss://your-domain.com/gateway-ws
|
||||
```
|
||||
|
|
|
|||
|
|
@ -18,10 +18,12 @@ export function ConnectionStatus({
|
|||
}: ConnectionStatusProps) {
|
||||
const { connection } = useMissionControl()
|
||||
const displayUrl = connection.url || 'ws://<gateway-host>:<gateway-port>'
|
||||
const isGatewayOptional = process.env.NEXT_PUBLIC_GATEWAY_OPTIONAL === 'true'
|
||||
|
||||
const getStatusColor = () => {
|
||||
if (isConnected) return 'bg-green-500 animate-pulse'
|
||||
if (connection.reconnectAttempts > 0) return 'bg-yellow-500'
|
||||
if (isGatewayOptional && !isConnected) return 'bg-blue-500'
|
||||
return 'bg-red-500'
|
||||
}
|
||||
|
||||
|
|
@ -32,6 +34,9 @@ export function ConnectionStatus({
|
|||
if (connection.reconnectAttempts > 0) {
|
||||
return `Reconnecting... (${connection.reconnectAttempts}/10)`
|
||||
}
|
||||
if (isGatewayOptional && !isConnected) {
|
||||
return 'Gateway Optional (Standalone)'
|
||||
}
|
||||
return 'Disconnected'
|
||||
}
|
||||
|
||||
|
|
|
|||
Loading…
Reference in New Issue