Console Gateway¶
The console gateway is a small, dedicated Go service that carries long-lived WebSocket streams for VM consoles. Long-lived WSS streams never touch PHP-FPM.
Why a separate service¶
- The browser talks only to the gateway — never to the provider.
- Provider coordinates (URL, ticket, auth header) stay server-side.
- The one-time console token is consumed atomically by the panel and stored only as a hash.
Run¶
PTEROCLOUD_PANEL_URL=https://panel.example.com \
PTEROCLOUD_GATEWAY_ID=gateway-1 \
PTEROCLOUD_GATEWAY_SECRET=YOUR_PROVIDER_TOKEN \
PTEROCLOUD_BIND=127.0.0.1:8687 \
PTEROCLOUD_ALLOWED_ORIGIN=https://panel.example.com \
./pterocloud-console-gateway serve
| Variable | Purpose |
|---|---|
PTEROCLOUD_PANEL_URL |
The panel base URL (must be HTTPS unless explicitly allowed for local testing). |
PTEROCLOUD_GATEWAY_ID |
Stable gateway identifier. |
PTEROCLOUD_GATEWAY_SECRET |
Shared secret for the gateway internal API. |
PTEROCLOUD_BIND |
Listen address (default 127.0.0.1:8687). |
PTEROCLOUD_PUBLIC_URL |
The public WebSocket URL customers dial. |
PTEROCLOUD_ALLOWED_ORIGIN |
Exact-match origin allowlist. Wildcards are rejected. |
PTEROCLOUD_ALLOW_INSECURE |
true only for local testing. |
Secrets
The gateway secret is a credential. Store it in a 0600 file and never
screenshot or log it. This documentation uses placeholders.
Reverse proxy¶
Put the gateway behind the same domain (recommended) or a dedicated origin that is added to the allowlist:
location /pterocloud-console/ {
proxy_pass http://127.0.0.1:8687;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
proxy_read_timeout 1h;
}
Behaviour¶
- Origin — exact-match allowlist; wildcard rejected.
- Token — consumed by the panel (atomic single-use with a replay cache; fail-closed).
- Proxy — binary frames both ways, 1 MiB frame cap, 15 s upstream dial.
- Revocation — polls the panel and closes matching sockets.
- Heartbeat — version/sessions/capacity every 15 s; auto-registers.
- Metrics —
/metricswith safe labels only (counts, bytes, latency). - Graceful shutdown — SIGTERM stops accepting, closes sessions and sends a final heartbeat. A restart drops sessions; customers reconnect with fresh tokens.
Register and check¶
php artisan pterocloud:console:gateways
php artisan pterocloud:console:inspect <instance_uuid>
php artisan pterocloud:console:session <session_uuid>
None of these commands print a token.