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