Docker
Tenzro Network provides official Docker images for running validator nodes, RPC nodes, and full network infrastructure. This guide covers building, configuring, and deploying Tenzro nodes using Docker and Docker Compose.
Official Docker Images
Docker images are built using multi-stage builds and can be hosted in your container registry. Images are typically built on CI/CD pipelines for version tracking.
Registry: Your container registry (GCR, ECR, ACR, Docker Hub)
Image: tenzro-node
Tags: latest, version tags, git commit SHA
Architecture: x86_64, aarch64 (multi-arch)
Dockerfile Configuration
The official Dockerfile uses multi-stage builds to produce minimal production images. The build process compiles the protocol modules and produces a single statically-linked binary.
# Multi-stage Dockerfile for tenzro-node
# Stage 1: Build environment
FROM rust:1.75-slim-bookworm AS builder
# Install build dependencies
RUN apt-get update && apt-get install -y \
build-essential \
pkg-config \
libssl-dev \
cmake \
git \
&& rm -rf /var/lib/apt/lists/*
WORKDIR /build
# Copy workspace configuration
COPY Cargo.toml Cargo.lock rust-toolchain.toml ./
COPY crates/ crates/
# Build release binary with optimizations
RUN cargo build --release --bin tenzro-node
# Stage 2: Minimal runtime image
FROM debian:bookworm-slim
# Install runtime dependencies only
RUN apt-get update && apt-get install -y \
ca-certificates \
libssl3 \
&& rm -rf /var/lib/apt/lists/*
# Create non-root user
RUN useradd -m -u 1000 tenzro
# Copy binary from builder
COPY --from=builder /build/target/release/tenzro-node /usr/local/bin/
# Set permissions
RUN chown tenzro:tenzro /usr/local/bin/tenzro-node
# Create data directory
RUN mkdir -p /data && chown tenzro:tenzro /data
USER tenzro
WORKDIR /data
# Expose ports
EXPOSE 9000 8545 8080 3001 3002
# Default command
ENTRYPOINT ["/usr/local/bin/tenzro-node"]
CMD ["--data-dir", "/data"]Build Arguments and Optimization
Production builds use Rust release optimizations with link-time optimization (LTO) and codegen-units=1 for maximum performance. Build time is approximately 15-20 minutes on modern hardware.
# Cargo.toml release profile
[profile.release]
opt-level = 3
lto = "fat"
codegen-units = 1
strip = true
panic = "abort"Building Docker Images
Build the Docker image locally from the repository root. The build context includes all workspace crates.
# Build with default tag
docker build -t tenzro-node:latest .
# Build with specific tag and platform
docker build -t tenzro-node:v0.1.0 --platform linux/amd64 .
# Multi-architecture build (requires buildx)
docker buildx build --platform linux/amd64,linux/arm64 \
-t tenzro-node:latest --push .
# Build with cache mount for faster rebuilds
docker build --cache-from tenzro-node:latest \
-t tenzro-node:dev .Running Containers
Validator Node
Run a validator node with persistent data storage and exposed ports for P2P networking, JSON-RPC, and protocol servers.
# Run validator with volume mount
docker run -d \
--name tenzro-validator \
--restart unless-stopped \
-p 9000:9000 \
-p 8545:8545 \
-p 8080:8080 \
-v tenzro-data:/data \
tenzro-node:latest \
--role validator \
--listen-addr /ip4/0.0.0.0/tcp/9000 \
--rpc-addr 0.0.0.0:8545 \
--data-dir /data
# View logs
docker logs -f tenzro-validator
# Check node status
docker exec tenzro-validator tenzro-node --helpRPC Node
RPC nodes serve JSON-RPC queries without participating in consensus. They require fewer resources than validators.
# Run RPC node
docker run -d \
--name tenzro-rpc \
--restart unless-stopped \
-p 8545:8545 \
-p 8080:8080 \
-p 3001:3001 \
-p 3002:3002 \
-v tenzro-rpc-data:/data \
tenzro-node:latest \
--role light-client \
--rpc-addr 0.0.0.0:8545 \
--mcp-addr 0.0.0.0:3001 \
--a2a-addr 0.0.0.0:3002 \
--data-dir /dataEnvironment Variables
Configure node behavior using environment variables instead of CLI arguments. All configuration options support environment variable overrides.
# Environment variable reference
TENZRO_ROLE=validator # Node role
TENZRO_DATA_DIR=/data # Data directory
TENZRO_LISTEN_ADDR=/ip4/0.0.0.0/tcp/9000
TENZRO_RPC_ADDR=0.0.0.0:8545
TENZRO_MCP_ADDR=0.0.0.0:3001
TENZRO_A2A_ADDR=0.0.0.0:3002
TENZRO_BOOT_NODES=/ip4/... # Bootstrap nodes
TENZRO_CHAIN_ID=1337 # Chain ID
RUST_LOG=info # Log level
# Run with environment file
docker run -d \
--name tenzro-node \
--env-file tenzro.env \
-v tenzro-data:/data \
tenzro-node:latestVolume Persistence
Persistent storage is critical for validators and RPC nodes. The data directory contains RocksDB databases, snapshots, and keystore files.
Volume Structure
/data/
├── rocksdb/ # RocksDB storage
│ ├── blocks/ # CF_BLOCKS
│ ├── state/ # CF_STATE
│ ├── accounts/ # CF_ACCOUNTS
│ ├── transactions/ # CF_TRANSACTIONS
│ ├── metadata/ # CF_METADATA
│ ├── snapshots/ # CF_SNAPSHOTS
│ ├── settlements/ # CF_SETTLEMENTS
│ ├── channels/ # CF_CHANNELS
│ └── challenges/ # CF_CHALLENGES
├── snapshots/ # State snapshots
├── keystore/ # Encrypted keystores
└── logs/ # Node logsNamed volumes provide portability and backup capabilities. Use bind mounts for direct host filesystem access.
# Create named volume
docker volume create tenzro-data
# Inspect volume
docker volume inspect tenzro-data
# Backup volume
docker run --rm \
-v tenzro-data:/data \
-v $(pwd):/backup \
alpine tar czf /backup/tenzro-backup.tar.gz /data
# Restore volume
docker run --rm \
-v tenzro-data:/data \
-v $(pwd):/backup \
alpine tar xzf /backup/tenzro-backup.tar.gz -C /
# Use bind mount (development only)
docker run -d \
-v /host/path/data:/data \
tenzro-node:latestDocker Compose
Docker Compose orchestrates multi-node deployments with networking, volumes, and service dependencies. This configuration runs a 3-validator network with 1 RPC node.
# docker-compose.yml
version: '3.8'
services:
validator-1:
image: tenzro-node:latest
container_name: tenzro-validator-1
restart: unless-stopped
ports:
- "9001:9000"
- "8546:8545"
volumes:
- validator-1-data:/data
environment:
TENZRO_ROLE: validator
TENZRO_DATA_DIR: /data
TENZRO_LISTEN_ADDR: /ip4/0.0.0.0/tcp/9000
RUST_LOG: info
networks:
- tenzro-net
validator-2:
image: tenzro-node:latest
container_name: tenzro-validator-2
restart: unless-stopped
ports:
- "9002:9000"
- "8547:8545"
volumes:
- validator-2-data:/data
environment:
TENZRO_ROLE: validator
TENZRO_DATA_DIR: /data
TENZRO_LISTEN_ADDR: /ip4/0.0.0.0/tcp/9000
RUST_LOG: info
networks:
- tenzro-net
depends_on:
- validator-1
validator-3:
image: tenzro-node:latest
container_name: tenzro-validator-3
restart: unless-stopped
ports:
- "9003:9000"
- "8548:8545"
volumes:
- validator-3-data:/data
environment:
TENZRO_ROLE: validator
TENZRO_DATA_DIR: /data
TENZRO_LISTEN_ADDR: /ip4/0.0.0.0/tcp/9000
RUST_LOG: info
networks:
- tenzro-net
depends_on:
- validator-1
- validator-2
rpc:
image: tenzro-node:latest
container_name: tenzro-rpc
restart: unless-stopped
ports:
- "8545:8545"
- "8080:8080"
- "3001:3001"
- "3002:3002"
volumes:
- rpc-data:/data
environment:
TENZRO_ROLE: light-client
TENZRO_DATA_DIR: /data
TENZRO_RPC_ADDR: 0.0.0.0:8545
TENZRO_MCP_ADDR: 0.0.0.0:3001
TENZRO_A2A_ADDR: 0.0.0.0:3002
RUST_LOG: info
networks:
- tenzro-net
depends_on:
- validator-1
- validator-2
- validator-3
networks:
tenzro-net:
driver: bridge
volumes:
validator-1-data:
validator-2-data:
validator-3-data:
rpc-data:Compose Commands
# Start all services
docker-compose up -d
# View logs for all services
docker-compose logs -f
# View logs for specific service
docker-compose logs -f validator-1
# Stop all services
docker-compose down
# Stop and remove volumes (WARNING: data loss)
docker-compose down -v
# Restart specific service
docker-compose restart rpc
# Scale RPC nodes
docker-compose up -d --scale rpc=3
# Check service status
docker-compose psHealth Checks
Docker health checks ensure nodes are running correctly. The health check queries the Web API health endpoint.
# Add to Dockerfile
HEALTHCHECK --interval=30s --timeout=10s --start-period=60s --retries=3 \
CMD curl -f http://localhost:8080/health || exit 1
# Or in docker-compose.yml
services:
validator-1:
image: tenzro-node:latest
healthcheck:
test: ["CMD", "curl", "-f", "http://localhost:8080/health"]
interval: 30s
timeout: 10s
start_period: 60s
retries: 3
# Check health status
docker inspect --format='{{json .State.Health}}' tenzro-validatorResource Limits
Set CPU and memory limits to prevent resource exhaustion. Validators require more resources than RPC nodes.
Validator Node:
CPU: 4 cores minimum (8 cores recommended)
Memory: 8 GB minimum (16 GB recommended)
Storage: 100 GB SSD minimum
RPC Node:
CPU: 2 cores minimum (4 cores recommended)
Memory: 4 GB minimum (8 GB recommended)
Storage: 50 GB SSD minimum
# Set resource limits
docker run -d \
--cpus="4" \
--memory="8g" \
--memory-swap="8g" \
--pids-limit=4096 \
tenzro-node:latest
# In docker-compose.yml
services:
validator-1:
image: tenzro-node:latest
deploy:
resources:
limits:
cpus: '4'
memory: 8G
reservations:
cpus: '2'
memory: 4GProduction Deployment
Production deployments use CI/CD pipelines for automated image builds with container registry storage. Images are tagged with git commit SHAs for version tracking.
# Example CI/CD pipeline configuration
# Build and push Docker images with version tags
docker build -t your-registry/tenzro-node:$GIT_SHA .
docker build -t your-registry/tenzro-node:latest .
docker push your-registry/tenzro-node:$GIT_SHA
docker push your-registry/tenzro-node:latest
# Deploy to Kubernetes
kubectl set image deployment/tenzro-rpc \
tenzro-node=your-registry/tenzro-node:$GIT_SHATroubleshooting
Container Won't Start
# Check container logs
docker logs tenzro-validator
# Inspect container configuration
docker inspect tenzro-validator
# Check if ports are already bound
netstat -tulpn | grep -E '9000|8545|8080'
# Run with shell for debugging
docker run -it --entrypoint /bin/sh tenzro-node:latestVolume Permission Issues
# Check volume permissions
docker run --rm -v tenzro-data:/data alpine ls -la /data
# Fix ownership (Linux only)
docker run --rm \
-v tenzro-data:/data \
alpine chown -R 1000:1000 /dataNetwork Connectivity
# Test RPC connectivity
curl http://localhost:8545 -X POST \
-H "Content-Type: application/json" \
-d '{"jsonrpc":"2.0","method":"eth_blockNumber","params":[],"id":1}'
# Test health endpoint
curl http://localhost:8080/health
# Check container network
docker network inspect bridge