Documentation Index
Fetch the complete documentation index at: https://mintlify.com/brimblehq/rexec/llms.txt
Use this file to discover all available pages before exploring further.
Ruby SDK
The official Ruby SDK for Rexec provides an idiomatic Ruby interface for Terminal as a Service.
Installation
Add to your Gemfile:
Or install directly:
Requirements
- Ruby 3.0+
faraday for HTTP requests
websocket-client-simple for terminal connections
Quick Start
require 'rexec'
client = Rexec::Client.new("https://your-instance.com", "your-token")
# Create a container
container = client.containers.create(
image: "ubuntu:24.04",
name: "my-sandbox"
)
puts "Created container: #{container.id}"
# Connect to terminal
terminal = client.terminal.connect(container.id)
terminal.on_data { |data| print data }
terminal.on_close { puts "\nConnection closed" }
terminal.write("echo 'Hello from Rexec!'\n")
sleep 2 # Wait for output
# Clean up
terminal.close
client.containers.delete(container.id)
Client Initialization
Basic Client
require 'rexec'
client = Rexec::Client.new(
"https://your-instance.com",
"your-api-token"
)
The main module is defined at /home/daytona/workspace/source/sdk/ruby/lib/rexec.rb:24.
With Options
client = Rexec::Client.new(
"https://your-instance.com",
"your-api-token",
timeout: 30 # optional
)
Container Operations
The Containers service provides methods for managing sandboxed environments.
List Containers
containers = client.containers.list
containers.each do |c|
puts "#{c.name}: #{c.status}"
end
Get Container
container = client.containers.get(container_id)
puts "Container #{container.name} is #{container.status}"
Create Container
container = client.containers.create(
image: "ubuntu:24.04",
name: "my-container",
environment: { "MY_VAR" => "value", "DEBUG" => "true" },
labels: { "project" => "demo" }
)
puts "Created: #{container.id}"
Start Container
client.containers.start(container_id)
Stop Container
client.containers.stop(container_id)
Delete Container
client.containers.delete(container_id)
File Operations
Manage files and directories within containers.
List Files
files = client.files.list(container_id, "/home")
files.each do |f|
icon = f.directory? ? "📁" : "📄"
puts "#{icon} #{f.name}"
end
Download File
content = client.files.download(container_id, "/etc/passwd")
puts content
Create Directory
client.files.mkdir(container_id, "/home/mydir")
Delete File
client.files.delete(container_id, "/home/file.txt")
Terminal Operations
Connect to containers via WebSocket for real-time terminal access.
Connect to Terminal
terminal = client.terminal.connect(container_id)
# With custom size
terminal = client.terminal.connect(container_id, cols: 120, rows: 40)
Handle Terminal Events
# Handle output
terminal.on_data do |data|
print data
end
# Handle close
terminal.on_close do
puts "Connection closed"
end
# Handle errors
terminal.on_error do |error|
puts "Error: #{error}"
end
Write to Terminal
terminal.write("ls -la\n")
terminal.write("cd /home && pwd\n")
Resize Terminal
Close Terminal
Advanced Examples
Run a Script
def run_script(client, container_id, script)
output = []
done = false
terminal = client.terminal.connect(container_id)
terminal.on_data { |data| output << data }
terminal.on_close { done = true }
terminal.write("#{script}\nexit\n")
sleep 0.1 until done
output.join
end
# Usage
result = run_script(
client,
container.id,
"apt update && apt install -y curl"
)
puts result
Batch Container Operations
require 'concurrent'
def create_batch(client, count)
futures = (0...count).map do |i|
Concurrent::Future.execute do
client.containers.create(
image: "ubuntu:24.04",
name: "worker-#{i}"
)
end
end
futures.map(&:value)
end
# Create 5 containers in parallel
containers = create_batch(client, 5)
puts "Created #{containers.length} containers"
File Upload
def upload_file(client, container_id, local_path, remote_path)
content = File.read(local_path)
client.files.upload(container_id, remote_path, content)
end
# Usage
upload_file(
client,
container.id,
'./local-script.sh',
'/home/script.sh'
)
Directory Sync
require 'find'
def sync_directory(client, container_id, local_dir, remote_dir)
client.files.mkdir(container_id, remote_dir)
Find.find(local_dir) do |path|
next unless File.file?(path)
relative_path = path.sub(local_dir, '')
remote_path = File.join(remote_dir, relative_path)
content = File.read(path)
client.files.upload(container_id, remote_path, content)
puts "Uploaded: #{remote_path}"
end
end
# Usage
sync_directory(
client,
container.id,
'./local-dir',
'/app'
)
Real-time Log Streaming
def stream_logs(client, container_id, command)
terminal = client.terminal.connect(container_id)
terminal.on_data do |data|
print data
# Could also save to file
# File.open('logs.txt', 'a') { |f| f.write(data) }
end
terminal.on_close do
puts "\nStream ended"
end
terminal.write("#{command}\n")
# Keep the connection open
sleep
end
# Usage
stream_logs(client, container.id, "tail -f /var/log/app.log")
def interactive_session(client, container_id)
terminal = client.terminal.connect(container_id)
# Handle output
terminal.on_data do |data|
print data
end
# Handle input from stdin
Thread.new do
while input = STDIN.gets
terminal.write(input)
end
end
# Keep connection open
sleep
end
# Usage
interactive_session(client, container.id)
Error Handling
begin
container = client.containers.get("invalid-id")
rescue Rexec::APIError => e
puts "API Error #{e.status_code}: #{e.message}"
rescue Rexec::ConnectionError => e
puts "Connection Error: #{e.message}"
rescue StandardError => e
puts "Unexpected error: #{e.message}"
end
Blocks and Iteration
The SDK uses idiomatic Ruby patterns:
# Iterate over containers
client.containers.list.each do |container|
puts container.name
end
# Use blocks for callbacks
terminal.on_data { |data| process(data) }
# Chainable methods
container = client.containers
.create(image: "ubuntu:24.04")
.tap { |c| puts "Created: #{c.id}" }
Thread Safety
The Ruby SDK uses thread-safe operations for concurrent access:
require 'concurrent'
# Create thread pool
pool = Concurrent::FixedThreadPool.new(5)
# Execute tasks in parallel
10.times do |i|
pool.post do
container = client.containers.create(
image: "ubuntu:24.04",
name: "worker-#{i}"
)
puts "Created: #{container.id}"
end
end
pool.shutdown
pool.wait_for_termination
Source Code
View the full source code on GitHub:
License
MIT License - see LICENSE for details.