Skip to main content

Docker Deployment

CycBox provides a Docker image for running workflows in headless environments such as servers, edge gateways, and CI pipelines. This is useful when you want to deploy an automated IoT workflow without the GUI.

Overview

CycBox can export a complete workflow — including Lua script logic and connection configuration — as a single .lua file. This file can then be run directly using the cycbox-cli binary or inside a Docker container.

Exported Lua Config File

A CycBox Lua config file contains both the Lua script code and a JSON configuration block embedded in a multi-line comment at the end. For example:

-- EID041 Modbus Temperature & Humidity Sensor to MQTT Publisher

local SLAVE_ADDR = 3
local POLL_INTERVAL = 5000
local MQTT_TOPIC = "cycbox/eid041"
local MQTT_CONNECTION_ID = 1

function on_start()
log("info", "=== EID041 Modbus Sensor Script Started ===")
end

local last_poll_time = nil
function on_timer(timestamp_ms)
if last_poll_time == nil or timestamp_ms - last_poll_time >= POLL_INTERVAL then
modbus_rtu_read_input_registers(SLAVE_ADDR, 0x0000, 6, 0, 0)
last_poll_time = timestamp_ms
end
end

function on_receive()
-- process messages ...
return true
end

--[[
{
"version": "1.8.1",
"name": "EID041 Modbus RTU to MQTT",
"configs": [
{
"app": {
"app_transport": "serial",
"app_codec": "modbus_rtu_codec"
},
"serial": {
"serial_port": "/dev/ttyUSB0",
"serial_baud_rate": 9600
}
},
{
"app": {
"app_transport": "mqtt"
},
"mqtt": {
"mqtt_broker_url": "mqtt://broker.emqx.io:1883",
"mqtt_client_id": "cycbox_eid041"
}
}
]
}
]]

The JSON block defines the connections (transports, codecs, and their parameters), while the Lua code above it implements the runtime logic. You can export this file from the CycBox GUI or write it by hand.

Running with Docker

The CycBox Docker image is available at ghcr.io/cycbox/cycbox:latest and supports both amd64 and arm64 architectures.

Quick Start

docker run --rm \
-v ./config.lua:/config/config.lua:ro \
ghcr.io/cycbox/cycbox:latest

This mounts your local config.lua into the container and runs it.

Accessing Serial Devices

To access host serial devices (e.g., /dev/ttyUSB0), run the container in privileged mode and mount /dev:

docker run --rm \
--privileged \
-v /dev:/dev \
-v ./config.lua:/config/config.lua:ro \
ghcr.io/cycbox/cycbox:latest

Alternatively, pass only the specific device:

docker run --rm \
--device /dev/ttyUSB0 \
-v ./config.lua:/config/config.lua:ro \
ghcr.io/cycbox/cycbox:latest

Using a Custom Config Path

By default, cycbox-cli reads /config/config.lua. To use a different path:

docker run --rm \
-v ./my_workflow.lua:/app/my_workflow.lua:ro \
ghcr.io/cycbox/cycbox:latest \
--config /app/my_workflow.lua

Enabling Debug Logging

docker run --rm \
-v ./config.lua:/config/config.lua:ro \
ghcr.io/cycbox/cycbox:latest \
--config /config/config.lua --debug

Running with Docker Compose

For persistent deployments, Docker Compose is recommended. Create a compose.yaml file:

services:
cycbox:
image: ghcr.io/cycbox/cycbox:latest
container_name: cycbox
# Required for accessing serial devices on the host
privileged: true
volumes:
- /dev:/dev
- ./config.lua:/config/config.lua:ro
restart: unless-stopped

Then start the service:

docker compose up -d

Useful Commands

# View logs
docker compose logs -f cycbox

# Stop the service
docker compose down

# Restart after updating config.lua
docker compose restart cycbox

Stopping

cycbox-cli handles SIGINT and SIGTERM gracefully, so both docker stop and Ctrl+C will shut down the engine cleanly.