* No commit suggestions generated * No commit suggestions generated * No commit suggestions generated
15 KiB
Docker Containers
This document describes all Docker containers used in the Sonr testnet architecture.
Overview
The testnet consists of 7 containers organized in a validator-sentry architecture:
- 3 Validators (private, isolated networks)
- 3 Sentry Nodes (public-facing, Cloudflare tunnel integration)
- 1 IPFS Node (distributed storage)
All containers use the unless-stopped restart policy for resilience.
Container Architecture
┌─────────────────────────────────────────────────────────┐
│ Cloudflare Tunnel (DockFlare) │
└────────────────────┬────────────────────────────────────┘
│
┌────────────────┴────────────────────┐
│ net-public + cloudflare-net │
│ │
│ ┌──────────┐ ┌──────────┐ ┌──────────┐ ┌──────┐
│ │ sentry- │ │ sentry- │ │ sentry- │ │ IPFS │
│ │ alice │◄─► bob │◄─► carol │ │ │
│ └────┬─────┘ └────┬─────┘ └────┬─────┘ └──────┘
└───────┼─────────────┼─────────────┼─────────────────┘
│ │ │
│ private │ private │ private
│ │ │
┌───────▼──────┐ ┌────▼──────┐ ┌────▼──────┐
│ val-alice │ │ val-bob │ │ val-carol │
│ (net-alice) │ │ (net-bob) │ │(net-carol)│
└──────────────┘ └───────────┘ └───────────┘
Validator Containers
Validators are the core consensus nodes that produce blocks and maintain blockchain state. They are isolated on private networks for security.
val-alice
Purpose: Alice's validator node
Image: onsonr/snrd:latest
Network: net-alice (private)
Volume: ./val-alice:/root/.sonr
Configuration:
- Chain ID:
sonrtest_1-1 - Moniker:
val-alice - Pruning: Disabled (
--pruning=nothing) - Min Gas Prices:
0usnr(free for testnet)
Security Features:
- Runs on isolated private network
- Only connects to its own sentry (
sentry-alice) - No direct public access
- Protected by sentry's
private_peer_idsconfiguration
Data Directory:
./val-alice/
├── config/
│ ├── genesis.json # Genesis state
│ ├── config.toml # Tendermint config
│ ├── app.toml # Application config
│ └── priv_validator_key.json # Validator signing key (CRITICAL!)
└── data/ # Blockchain data
val-bob
Purpose: Bob's validator node
Image: onsonr/snrd:latest
Network: net-bob (private)
Volume: ./val-bob:/root/.sonr
Configuration:
- Chain ID:
sonrtest_1-1 - Moniker:
val-bob - Pruning: Disabled
- Min Gas Prices:
0usnr
Security: Same as val-alice, isolated on net-bob
val-carol
Purpose: Carol's validator node
Image: onsonr/snrd:latest
Network: net-carol (private)
Volume: ./val-carol:/root/.sonr
Configuration:
- Chain ID:
sonrtest_1-1 - Moniker:
val-carol - Pruning: Disabled
- Min Gas Prices:
0usnr
Security: Same as val-alice, isolated on net-carol
Sentry Containers
Sentry nodes act as a protective layer between validators and the public internet. They handle all public RPC, REST, gRPC, and EVM requests while shielding validator identities.
sentry-alice
Purpose: Alice's public-facing sentry node
Image: onsonr/snrd:latest
Networks:
net-alice(connects to val-alice)net-public(connects to other sentries)cloudflare-net(for DockFlare tunnels)
Volume: ./sentry-alice:/root/.sonr
Depends On: val-alice
Configuration:
- Chain ID:
sonrtest_1-1 - Moniker:
sentry-alice - Pruning: Disabled
- Min Gas Prices:
0usnr
Exposed Services:
- RPC: Port 26657 (Tendermint RPC)
- REST: Port 1317 (Cosmos REST API)
- gRPC: Port 9090 (gRPC endpoint)
- EVM JSON-RPC: Port 8545 (Ethereum-compatible)
- EVM WebSocket: Port 8546 (WebSocket subscriptions)
JSON-RPC APIs Enabled:
eth- Ethereum JSON-RPCtxpool- Transaction pool inspectionpersonal- Account managementnet- Network infodebug- Debugging APIsweb3- Web3 utilities
Cloudflare Tunnel Endpoints:
| Endpoint | Hostname | Internal Service | Description |
|---|---|---|---|
| RPC | alice-rpc.sonr.land |
http://sentry-alice:26657 |
Tendermint RPC for queries and transactions |
| REST | alice-rest.sonr.land |
http://sentry-alice:1317 |
Cosmos REST API (LCD) |
| gRPC | alice-grpc.sonr.land |
http://sentry-alice:9090 |
gRPC for efficient binary communication |
| EVM | alice-evm.sonr.land |
http://sentry-alice:8545 |
EVM JSON-RPC (MetaMask compatible) |
Peer Connections:
- Persistent Peer:
val-alice(private connection) - Seeds:
sentry-bob,sentry-carol(public P2P) - Private Peer IDs: Marks
val-aliceas private to hide from network
Security Features:
- Shields validator from direct exposure
- Handles all public-facing traffic
- Rate limiting and DDoS protection via Cloudflare
- TLS encryption via Cloudflare tunnels
sentry-bob
Purpose: Bob's public-facing sentry node
Image: onsonr/snrd:latest
Networks: net-bob, net-public, cloudflare-net
Volume: ./sentry-bob:/root/.sonr
Depends On: val-bob
Configuration: Same as sentry-alice, with moniker sentry-bob
Cloudflare Tunnel Endpoints:
bob-rpc.sonr.land→ RPC (26657)bob-rest.sonr.land→ REST (1317)bob-grpc.sonr.land→ gRPC (9090)bob-evm.sonr.land→ EVM JSON-RPC (8545)
Peer Connections:
- Persistent Peer:
val-bob - Seeds:
sentry-alice,sentry-carol
sentry-carol
Purpose: Carol's public-facing sentry node
Image: onsonr/snrd:latest
Networks: net-carol, net-public, cloudflare-net
Volume: ./sentry-carol:/root/.sonr
Depends On: val-carol
Configuration: Same as sentry-alice, with moniker sentry-carol
Cloudflare Tunnel Endpoints:
carol-rpc.sonr.land→ RPC (26657)carol-rest.sonr.land→ REST (1317)carol-grpc.sonr.land→ gRPC (9090)carol-evm.sonr.land→ EVM JSON-RPC (8545)
Peer Connections:
- Persistent Peer:
val-carol - Seeds:
sentry-alice,sentry-bob
IPFS Container
ipfsctl
Purpose: Distributed file storage and content addressing
Image: ipfs/kubo:latest (official IPFS implementation)
Networks:
net-public(connects to sentry nodes)cloudflare-net(for DockFlare tunnels)
Volume: ipfs-data:/data/ipfs (named volume)
Configuration:
- IPFS Profile:
server(optimized for server deployment)
Exposed Services:
- API: Port 5001 (IPFS HTTP API)
- Gateway: Port 8080 (IPFS Gateway for content retrieval)
- Swarm: Port 4001 (P2P networking)
Cloudflare Tunnel Endpoints:
| Endpoint | Hostname | Internal Service | Description |
|---|---|---|---|
| API | ipfs-api.sonr.land |
http://ipfsctl:5001 |
IPFS API for adding/pinning content |
| Gateway | ipfs-gateway.sonr.land |
http://ipfsctl:8080 |
HTTP gateway for retrieving content |
Features:
- Content-Addressed Storage: Files identified by cryptographic hash (CID)
- Distributed Network: Connects to global IPFS network
- Persistent Storage: Data stored in named volume
- HTTP API: RESTful API for programmatic access
- Gateway Access: Retrieve content via HTTP using CID
Common Operations:
# Add file to IPFS
curl -X POST -F file=@myfile.txt https://ipfs-api.sonr.land/api/v0/add
# Retrieve file by CID
curl https://ipfs-gateway.sonr.land/ipfs/QmYwAPJzv5CZsnA625s3Xf2nemtYgPpHdWEz79ojWnPbdG/readme
# Check version
curl -X POST https://ipfs-api.sonr.land/api/v0/version | jq
Network Topology
Private Networks
Each validator has its own isolated network:
| Network | Purpose | Containers |
|---|---|---|
net-alice |
Alice validator isolation | val-alice, sentry-alice |
net-bob |
Bob validator isolation | val-bob, sentry-bob |
net-carol |
Carol validator isolation | val-carol, sentry-carol |
Security Benefits:
- Validators cannot directly communicate with each other
- Prevents Byzantine attacks at network layer
- Forces all communication through sentries
Public Network
| Network | Purpose | Containers |
|---|---|---|
net-public |
Sentry interconnection | sentry-alice, sentry-bob, sentry-carol, ipfsctl |
Purpose:
- Sentries discover and connect to each other
- IPFS accessible to all sentries
- Public P2P gossip network
Cloudflare Network
| Network | Purpose | Containers |
|---|---|---|
cloudflare-net |
DockFlare tunnel access | sentry-alice, sentry-bob, sentry-carol, ipfsctl |
Type: External (must be created before starting stack) Purpose: Allows DockFlare to discover and tunnel traffic to containers
Setup:
docker network create cloudflare-net
Volume Management
Bind Mounts (Validators & Sentries)
./val-alice:/root/.sonr
./val-bob:/root/.sonr
./val-carol:/root/.sonr
./sentry-alice:/root/.sonr
./sentry-bob:/root/.sonr
./sentry-carol:/root/.sonr
Advantages:
- Direct file system access from host
- Easy backup and inspection
- No permission issues (files owned by host user)
Backup:
tar -czf testnet-backup.tar.gz val-* sentry-*
Named Volume (IPFS)
ipfs-data:/data/ipfs
Advantages:
- Managed by Docker
- Better performance on some systems
- Automatic cleanup with
docker compose down -v
Backup:
docker run --rm -v ipfs-data:/data -v $(pwd):/backup alpine tar czf /backup/ipfs-backup.tar.gz /data
Container Management
Start All Containers
make start
# or
docker compose up -d
Stop All Containers
make stop
# or
docker compose down
View Container Logs
# All containers
docker compose logs -f
# Specific container
docker compose logs -f sentry-alice
# Last 100 lines
docker compose logs --tail=100 val-alice
Execute Commands in Containers
# Via bootstrap script
devbox run exec sentry-alice status
# Via docker compose
docker compose exec sentry-alice snrd status --home /root/.sonr
# Via docker
docker exec -it sentry-alice snrd keys list --keyring-backend test
Inspect Container Configuration
# View environment variables
docker inspect sentry-alice -f '{{json .Config.Env}}' | jq
# View networks
docker inspect sentry-alice -f '{{json .NetworkSettings.Networks}}' | jq
# View mounts
docker inspect sentry-alice -f '{{json .Mounts}}' | jq
Resource Usage
# Real-time stats
docker stats
# Container resource limits (if set)
docker inspect sentry-alice -f '{{json .HostConfig.Memory}}' | jq
Health Checks
Container Status
docker ps --filter "name=val-" --filter "name=sentry-" --filter "name=ipfs"
Node Sync Status
# Check if nodes are syncing
for container in sentry-alice sentry-bob sentry-carol; do
echo "=== $container ==="
docker exec $container sh -c 'curl -s http://localhost:26657/status | jq -r ".result.sync_info.catching_up"'
done
Block Height
# Current block height
docker exec sentry-alice sh -c 'curl -s http://localhost:26657/status | jq -r ".result.sync_info.latest_block_height"'
IPFS Health
# Check IPFS daemon
curl -X POST https://ipfs-api.sonr.land/api/v0/version | jq
# Check connected peers
curl -X POST https://ipfs-api.sonr.land/api/v0/swarm/peers | jq
Security Considerations
Validator Security
- Never expose validators directly - Always use sentries
- Backup
priv_validator_key.json- Cannot be recovered if lost - Monitor validator uptime - Downtime results in slashing
- Use KMS in production - Hardware security modules for key management
Sentry Security
- Rate limiting via Cloudflare - Protects against DDoS
- TLS encryption - All traffic encrypted via Cloudflare tunnels
- No exposed ports - All access via tunnels only
- Regular updates - Keep
onsonr/snrdimage updated
IPFS Security
- Content verification - All content verified by CID
- No private data - IPFS is a public network
- Pin important content - Prevent garbage collection
- Monitor storage - IPFS can grow large over time
Troubleshooting
Container Won't Start
# Check logs
docker compose logs <container-name>
# Check resource usage
docker stats
# Verify networks exist
docker network ls | grep -E "net-|cloudflare"
# Recreate container
docker compose up -d --force-recreate <container-name>
Permission Issues
# Fix ownership (if needed)
sudo chown -R $USER:$USER val-* sentry-*
# Check bind mount permissions
ls -la val-alice/
Network Connectivity Issues
# Test connectivity between containers
docker exec sentry-alice ping -c 3 val-alice
docker exec sentry-alice ping -c 3 sentry-bob
# Check network configuration
docker network inspect net-public
IPFS Issues
# Check IPFS daemon status
docker compose logs ipfsctl
# Restart IPFS
docker compose restart ipfsctl
# Clear IPFS cache (WARNING: destructive)
docker compose down
docker volume rm testnet_ipfs-data
docker compose up -d
Performance Tuning
Resource Limits (Optional)
Add to docker-compose.yml:
services:
val-alice:
deploy:
resources:
limits:
cpus: '2.0'
memory: 4G
reservations:
cpus: '1.0'
memory: 2G
Logging Configuration
Prevent log bloat:
services:
val-alice:
logging:
driver: "json-file"
options:
max-size: "100m"
max-file: "3"
Maintenance
Update Containers
# Pull latest images
docker compose pull
# Restart with new images
docker compose up -d
Clean Up
# Remove stopped containers
docker compose down
# Remove all data (WARNING: destructive)
docker compose down -v
# Clean Docker system
docker system prune -a
Backup Procedure
# Stop containers
make stop
# Backup data
tar -czf testnet-backup-$(date +%Y%m%d).tar.gz val-* sentry-* .env
# Backup IPFS volume
docker run --rm -v testnet_ipfs-data:/data -v $(pwd):/backup \
alpine tar czf /backup/ipfs-backup-$(date +%Y%m%d).tar.gz /data
# Restart containers
make start