Tenzro Testnet is live. Get testnet TNZO

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 --help

RPC 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 /data

Environment 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:latest

Volume 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 logs

Named 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:latest

Docker 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 ps

Health 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/api/health || exit 1

# Or in docker-compose.yml
services:
  validator-1:
    image: tenzro-node:latest
    healthcheck:
      test: ["CMD", "curl", "-f", "http://localhost:8080/api/health"]
      interval: 30s
      timeout: 10s
      start_period: 60s
      retries: 3

# Check health status
docker inspect --format='{{json .State.Health}}' tenzro-validator

Resource 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: 4G

Production 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_SHA

Troubleshooting

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:latest

Volume 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 /data

Network 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/api/health

# Check container network
docker network inspect bridge