Connection
Connect to a container’s WebSocket for real-time monitoring.
Endpoint: ws://localhost:8070/ws/:internal_id?token=<token>
const ws = new WebSocket('ws://localhost:8070/ws/my-server-001?token=lightd_token');
ws.onopen = () => {
console.log('Connected to container');
};
ws.onmessage = (event) => {
const data = JSON.parse(event.data);
console.log('Event:', data.event, data);
};
ws.onerror = (error) => {
console.error('WebSocket error:', error);
};
ws.onclose = () => {
console.log('Disconnected from container');
};
Authentication:
- Token passed as query parameter
- Token validated on connection
- Connection closed if token expires during session
- Single-use tokens are consumed on connection
Outbound Events (Server → Client)
Stats Event
Real-time container statistics with change detection.
{
"event": "stats",
"cpu_usage": 25.5,
"memory_usage": 134217728,
"memory_limit": 536870912,
"network_rx": 1024,
"network_tx": 2048,
"block_read": 4096,
"block_write": 8192
}
Fields:
cpu_usage - CPU percentage (0-100 per core)
memory_usage - Memory used in bytes
memory_limit - Memory limit in bytes
network_rx - Network bytes received
network_tx - Network bytes transmitted
block_read - Disk bytes read
block_write - Disk bytes written
Stats are only sent when values change (change detection enabled).
Console Output
Real-time console output from the container.
{
"event": "console",
"data": "Server started on port 25565\n"
}
Console Duplicate
Duplicate of console output for compatibility.
{
"event": "console duplicate",
"data": "Server started on port 25565\n"
}
Container State Events
Installing:
{
"event": "event",
"data": "installing"
}
Installed (Ready):
{
"event": "event",
"data": "installed"
}
Starting:
{
"event": "event",
"data": "starting"
}
Running (Pattern Matched):
{
"event": "event",
"data": "running"
}
Stopping:
{
"event": "event",
"data": "stopping"
}
Exit (Container Stopped):
{
"event": "event",
"data": "exit"
}
Daemon Messages
System messages from Lightd.
{
"event": "daemon_message",
"data": "Server started"
}
Common messages:
"Container started" - Container started successfully
"Server started" - Server detected as running (pattern matched)
"Container stopped" - Container stopped
"Container restarted" - Container restarted
"Error: <message>" - Error occurred
Historical Logs
Historical logs when requested.
{
"event": "logs",
"data": "Previous log line 1\nPrevious log line 2\n"
}
Inbound Events (Client → Server)
Send Command
Execute a command in the container.
ws.send(JSON.stringify({
event: 'send_command',
command: 'echo "Hello World"\n'
}));
Event:
{
"event": "send_command",
"command": "echo 'Hello World'\n"
}
Include \n at the end for command execution.
Power Actions
Start Container:
{
"event": "power",
"action": "start"
}
Kill Container:
{
"event": "power",
"action": "kill"
}
Restart Container:
{
"event": "power",
"action": "restart"
}
// Start
ws.send(JSON.stringify({
event: 'power',
action: 'start'
}));
// Kill
ws.send(JSON.stringify({
event: 'power',
action: 'kill'
}));
// Restart
ws.send(JSON.stringify({
event: 'power',
action: 'restart'
}));
Request Logs
Request historical logs from the container.
ws.send(JSON.stringify({
event: 'request_logs'
}));
Event:
{
"event": "request_logs"
}
Response: Server sends logs event with historical data.
Complete Example
// Connect to WebSocket
const ws = new WebSocket('ws://localhost:8070/ws/my-server-001?token=lightd_token');
// Handle connection open
ws.onopen = () => {
console.log('Connected to container');
// Request historical logs
ws.send(JSON.stringify({
event: 'request_logs'
}));
};
// Handle incoming messages
ws.onmessage = (event) => {
const data = JSON.parse(event.data);
switch(data.event) {
case 'console':
console.log('Console:', data.data);
break;
case 'stats':
console.log('CPU:', data.cpu_usage + '%');
console.log('Memory:', data.memory_usage, '/', data.memory_limit);
break;
case 'event':
console.log('State:', data.data);
break;
case 'daemon_message':
console.log('System:', data.data);
break;
case 'logs':
console.log('Historical logs:', data.data);
break;
}
};
// Handle errors
ws.onerror = (error) => {
console.error('WebSocket error:', error);
};
// Handle close
ws.onclose = () => {
console.log('Disconnected from container');
};
// Helper functions
function sendCommand(cmd) {
ws.send(JSON.stringify({
event: 'send_command',
command: cmd + '\n'
}));
}
function startContainer() {
ws.send(JSON.stringify({
event: 'power',
action: 'start'
}));
}
function stopContainer() {
ws.send(JSON.stringify({
event: 'power',
action: 'kill'
}));
}
function restartContainer() {
ws.send(JSON.stringify({
event: 'power',
action: 'restart'
}));
}
// Usage
sendCommand('echo "Hello from WebSocket"');
startContainer();
Connection Lifecycle
Connect
Client connects with token in query parameter
Validate
Server validates token
Subscribe
Client subscribed to container events
Stream
Real-time stats and console output streamed
Monitor
Token validity checked periodically
Disconnect
Connection closed if token expires or client disconnects
Error Handling
Invalid Token:
- Connection rejected with 401 status
- WebSocket closes immediately
Token Expired:
- Connection closes with close code
- Client should reconnect with new token
Container Not Found:
- Connection accepted but no events sent
- Client should verify container exists
- Stats sent only when values change (reduces bandwidth)
- Console output streamed in real-time
- Multiple clients can connect to same container
- Each client gets independent event stream
Best Practices
Implement automatic reconnection with exponential backoff for production applications.
Buffer outgoing messages if connection is temporarily lost to avoid data loss.
Filter events client-side based on your application needs to reduce processing overhead.
Monitor token expiration and refresh before it expires to maintain connection.