Skip to main content
Version: Next

Best Practices

This guide provides comprehensive best practices for using Merobox effectively, from workflow design to testing integration and performance optimization.

Workflow Design

1. Start Simple

Begin with basic workflows and gradually add complexity:

# Start with simple workflows
description: Simple workflow
name: Basic Workflow

nodes:
chain_id: testnet-1
count: 1
image: ghcr.io/calimero-network/merod:edge

steps:
- name: Basic Step
type: script
script: echo "Hello, Merobox!"

stop_all_nodes: true

2. Modular Steps

Break complex operations into smaller, focused steps:

# Good: Modular approach
steps:
- name: Setup Environment
type: script
script: |
echo "Setting up environment..."
# Setup logic

- name: Install Application
type: install_application
node: calimero-node-1
path: ./my-app.wasm

- name: Configure Application
type: script
script: |
echo "Configuring application..."
# Configuration logic

- name: Test Application
type: call
node: calimero-node-1
method: test_functionality

3. Clear Naming

Use descriptive names for steps and variables:

# Good: Descriptive names
steps:
- name: Install User Management Application
type: install_application
node: calimero-node-1
path: ./user-mgmt.wasm
outputs:
user_app_id: applicationId

- name: Create User Management Context
type: create_context
node: calimero-node-1
application_id: '{{user_app_id}}'
outputs:
user_context_id: contextId
admin_key: memberPublicKey

4. Error Handling

Include validation and error checking steps:

steps:
- name: Risky Operation
type: call
node: calimero-node-1
method: risky_method
retry:
attempts: 3
delay: 5
backoff: exponential
on_error:
- name: Log Error
type: script
script: echo "Operation failed: {{error}}"
- name: Cleanup
type: script
script: echo "Cleaning up..."

- name: Validate Results
type: assert
statements:
- '{{result}} != null'
- "contains({{result}}, 'expected_value')"

Testing Integration

1. Isolated Tests

Use separate node prefixes for different test suites:

# Use different prefixes for isolation
@pytest.fixture
def unit_test_cluster():
with cluster(count=1, prefix="unit") as env:
yield env

@pytest.fixture
def integration_test_cluster():
with cluster(count=3, prefix="integration") as env:
yield env

@pytest.fixture
def performance_test_cluster():
with cluster(count=5, prefix="performance") as env:
yield env

2. Resource Cleanup

Always clean up resources after tests:

@pytest.fixture
def test_cluster():
with cluster(count=2, prefix="test") as env:
try:
yield env
finally:
# Cleanup logic
print("Cleaning up test resources...")

3. Parallel Testing

Use different prefixes for parallel test execution:

# Enable parallel testing
pytestmark = pytest.mark.parallel

def test_parallel_1():
with cluster(count=1, prefix="parallel-1") as env:
# Test logic
pass

def test_parallel_2():
with cluster(count=1, prefix="parallel-2") as env:
# Test logic
pass

4. Environment Setup

Use workflows for complex test environment setup:

# workflows/test-setup.yml
description: Test environment setup
name: Test Setup

nodes:
chain_id: testnet-1
count: 3
image: ghcr.io/calimero-network/merod:edge
prefix: test-node

steps:
- name: Install Application
type: install_application
node: test-node-1
path: ./test-app.wasm
dev: true
outputs:
app_id: applicationId

- name: Create Context
type: create_context
node: test-node-1
application_id: '{{app_id}}'
outputs:
context_id: contextId
member_key: memberPublicKey

- name: Setup Test Data
type: call
node: test-node-1
context_id: '{{context_id}}'
executor_public_key: '{{member_key}}'
method: setup_test_data
args:
test_cases: 100

stop_all_nodes: false # Keep nodes running for tests

Performance Considerations

1. Minimal Waits

Use appropriate wait times, not excessive delays:

# Good: Minimal wait times
steps:
- name: Wait for Node
type: wait
seconds: 5 # Reasonable wait time
message: 'Waiting for node to start...'

# Bad: Excessive wait times
steps:
- name: Wait for Node
type: wait
seconds: 300 # Too long!

2. Resource Management

Stop nodes when not needed:

# Good: Stop nodes when done
stop_all_nodes: true

# Or stop specific nodes
steps:
- name: Stop Unused Nodes
type: script
script: |
merobox stop calimero-node-2
merobox stop calimero-node-3

3. Efficient Operations

Design workflows to minimize sequential dependencies:

# Good: Parallel operations
steps:
- name: Parallel Setup
type: parallel
steps:
- name: Setup Node 1
type: script
script: echo "Setting up node 1"
- name: Setup Node 2
type: script
script: echo "Setting up node 2"
- name: Setup Node 3
type: script
script: echo "Setting up node 3"

# Bad: Sequential operations
steps:
- name: Setup Node 1
type: script
script: echo "Setting up node 1"
- name: Setup Node 2
type: script
script: echo "Setting up node 2"
- name: Setup Node 3
type: script
script: echo "Setting up node 3"

4. Monitoring

Include health checks and monitoring in long-running workflows:

steps:
- name: Health Check
type: script
script: |
echo "Checking node health..."
curl -f http://calimero-node-1:2428/health
echo "Node is healthy"

- name: Monitor Performance
type: script
script: |
echo "Monitoring performance..."
# Add monitoring logic

Security Best Practices

1. Use Non-Root Users

nodes:
security:
user: '1000:1000' # Non-root user
read_only: true
no_new_privileges: true

2. Drop Unnecessary Capabilities

nodes:
security:
capabilities:
drop: ['ALL']
add: ['NET_BIND_SERVICE'] # Only add what's needed

3. Use Secrets Management

secrets:
- name: api-key
environment: API_KEY
required: true

nodes:
secrets:
- api-key
environment:
API_KEY_FILE: /run/secrets/api-key

4. Network Segmentation

networks:
- name: calimero-internal
driver: bridge
options:
com.docker.network.bridge.enable_icc: 'false'
com.docker.network.bridge.enable_ip_masquerade: 'true'

Configuration Management

1. Environment-Specific Configuration

# Use different configurations for different environments
development:
nodes:
count: 1
resources:
memory: '1G'
cpus: '0.5'
security:
read_only: false

production:
nodes:
count: 5
resources:
memory: '4G'
cpus: '2.0'
security:
read_only: true
no_new_privileges: true

2. Version Control

Track configuration changes in version control:

# Track workflow files
git add workflows/
git commit -m "Add new workflow configuration"

# Track environment files
git add .env.example
git commit -m "Update environment configuration"

3. Configuration Validation

Validate configuration before deployment:

steps:
- name: Validate Configuration
type: script
script: |
echo "Validating configuration..."
# Add validation logic
echo "Configuration is valid"

Monitoring and Observability

1. Comprehensive Monitoring

monitoring:
enabled: true
metrics:
- cpu_usage
- memory_usage
- disk_usage
- network_io
- application_metrics
alerts:
- metric: memory_usage
threshold: 80
action: restart_node

2. Logging

Include comprehensive logging:

steps:
- name: Log Important Events
type: script
script: |
echo "Starting important operation..."
# Operation logic
echo "Operation completed successfully"

3. Health Checks

Include health checks in workflows:

steps:
- name: Health Check
type: script
script: |
echo "Performing health check..."
curl -f http://calimero-node-1:2428/health
echo "Health check passed"

Troubleshooting

1. Debug Mode

Enable debug mode for troubleshooting:

# Enable debug logging
export LOG_LEVEL=DEBUG

# Run with verbose output
merobox bootstrap run workflow.yml --verbose

2. Resource Monitoring

Monitor resource usage:

# Check resource usage
docker stats $(docker ps -q --filter "name=calimero-")

# Check logs
merobox logs calimero-node-1

3. Network Diagnostics

Diagnose network issues:

# Check network connectivity
docker network ls
docker network inspect calimero-web

# Test connectivity
docker exec calimero-node-1 ping calimero-node-2

Documentation

1. Document Workflows

Include comprehensive documentation:

description: |
This workflow demonstrates how to set up a multi-node
Calimero cluster with authentication service integration.
It includes error handling, monitoring, and cleanup.
name: Multi-Node Auth Setup
# ... workflow steps

2. Document Configuration

Document configuration options:

# Configuration documentation
nodes:
# Number of nodes to create
count: 3

# Docker image to use
image: ghcr.io/calimero-network/merod:edge

# Resource limits
resources:
memory: '2G' # Memory limit per node
cpus: '1.0' # CPU limit per node

3. Document Dependencies

Document external dependencies:

# External dependencies
# - Docker must be running
# - Ports 2428, 2528, 2628 must be available
# - At least 4GB RAM and 2 CPU cores recommended

Common Pitfalls

1. Resource Exhaustion

Problem: Not enough resources for the workload.

Solution: Monitor resource usage and scale appropriately.

# Monitor resources
monitoring:
enabled: true
metrics:
- memory_usage
- cpu_usage
alerts:
- metric: memory_usage
threshold: 80
action: scale_up

2. Network Issues

Problem: Nodes can't communicate with each other.

Solution: Check network configuration and connectivity.

# Proper network configuration
networks:
- name: calimero-web
driver: bridge
options:
com.docker.network.bridge.enable_icc: 'true'

3. Timing Issues

Problem: Operations fail due to timing issues.

Solution: Use appropriate wait times and retry logic.

# Proper timing
steps:
- name: Wait for Node
type: wait
seconds: 10
message: 'Waiting for node to start...'

- name: Retry Operation
type: call
node: calimero-node-1
method: operation
retry:
attempts: 3
delay: 5

Next Steps

Now that you understand best practices:

Was this page helpful?
Need some help? Check Support page