Skip to main content

Running Your Own Beacon

rng.dev is fully open source under MIT license. You can run your own beacon with no restrictions or fees.


Why Self-Host?

  • Independence: Don't rely on our infrastructure
  • Customization: Add your own sources, change configuration
  • Privacy: Keep your usage patterns private
  • Compliance: Meet specific regulatory requirements

Prerequisites

  • Docker and Docker Compose
  • 2GB RAM minimum
  • API keys for some blockchain RPC providers (see below)

API Keys & RPC Providers

The beacon fetches data from 8 blockchains. Some have free public endpoints; others require API keys.

Required API Keys

ChainProviderFree TierGet Key
CardanoBlockfrost50,000 requests/dayblockfrost.io
SolanaHelius100,000 credits/mohelius.dev
ChainProviderFree TierGet Key
EthereumAlchemy300M compute units/moalchemy.com
ArbitrumAlchemyIncluded with EthereumSame key as Ethereum
BaseAlchemyIncluded with EthereumSame key as Ethereum

Free Public Endpoints (No Key Needed)

ChainDefault EndpointNotes
Aptosfullnode.mainnet.aptoslabs.comOfficial Aptos Labs node
Bitcoinmempool.space/apiCommunity-run, reliable
Suifullnode.mainnet.sui.ioOfficial Sui Foundation node

Fallback Strategy

Each chain has multiple fallback endpoints configured. If the primary fails, the beacon automatically rotates through:

  • Ankr — Free public RPCs for most chains
  • LlamaNodes — Free public RPCs
  • PublicNode — Free public RPCs

The beacon will operate with degraded reliability without API keys, but we recommend getting at least Blockfrost (Cardano) and Helius (Solana) keys for production use.


Quick Start

1. Clone the Repository

git clone https://github.com/hugoelliott/beacon.git
cd beacon

2. Configure Environment

cp .env.example .env

Edit .env with your API keys:

# Required: Cardano via Blockfrost (free tier: 50k requests/day)
# Get key at: https://blockfrost.io
BLOCKFROST_API_KEY=mainnetYourKeyHere

# Required: Solana via Helius (free tier: 100k credits/month)
# Get key at: https://helius.dev
HELIUS_API_KEY=your_helius_key

# Recommended: Alchemy for Ethereum/Arbitrum/Base (free tier: 300M CU/month)
# Get key at: https://alchemy.com
# One key works for all three chains
ALCHEMY_API_KEY=your_alchemy_key

# Database (defaults work for Docker Compose)
DATABASE_URL=postgresql+asyncpg://beacon:beacon@localhost:5432/beacon # pragma: allowlist secret

3. Start Services

docker-compose up -d

4. Verify It's Working

# Check health
curl http://localhost:8000/api/v1/health

# Get current round (after first second)
curl http://localhost:8000/api/v1/current

Configuration Options

Environment Variables

Core Settings

VariableDefaultDescription
BEACON_ROUND_DURATION_SECONDS1Duration of each beacon round
DEBUGfalseEnable debug logging
CORS_ORIGINSlocalhostComma-separated allowed origins

API Keys

VariableDefaultDescription
BLOCKFROST_API_KEY-Cardano Blockfrost API key
HELIUS_API_KEY-Solana Helius API key
ALCHEMY_API_KEY-Alchemy key (Ethereum/Arbitrum/Base)

Custom RPC Endpoints

Override default endpoints if you have your own nodes or preferred providers:

VariableDefaultDescription
APTOS_RPC_URLfullnode.mainnet.aptoslabs.comAptos REST API
BITCOIN_RPC_URLmempool.space/apiBitcoin API
CARDANO_RPC_URLcardano-mainnet.blockfrost.ioCardano Blockfrost
ETHEREUM_RPC_URLethereum-rpc.publicnode.comEthereum JSON-RPC
SOLANA_RPC_URLapi.mainnet-beta.solana.comSolana JSON-RPC
SUI_RPC_URLfullnode.mainnet.sui.ioSui JSON-RPC

Database

VariableDefaultDescription
DATABASE_URL-Full PostgreSQL connection string
DATABASE_HOSTlocalhostPostgreSQL host
DATABASE_PORT5432PostgreSQL port
DATABASE_USERbeaconPostgreSQL user
DATABASE_PASSWORDbeaconPostgreSQL password
DATABASE_NAMEbeaconPostgreSQL database name
POSTGRES_ROUNDS_RETENTION100000Rounds to keep (~27 hours)

Alerting

VariableDefaultDescription
ALERT_WEBHOOK_URL-Slack/Discord webhook for alerts
ALERT_COOLDOWN_SECONDS300Minimum time between duplicate alerts
ALERT_FAILURE_THRESHOLD3Consecutive failures before alerting

Optional Entropy Sources

Self-hosted operators can optionally add additional entropy sources beyond the standard blockchain inputs.

drand Integration

Add drand's threshold BLS signatures for applications requiring that specific proof type.

# config/entropy.yaml
optional_sources:
drand:
enabled: true
network: "quicknet"
wait_for_next: true # Wait for future round (front-running prevention)

Properties:

  • Adds ~1.5 second average latency (waiting for next drand round)
  • Provides BLS threshold signatures from 20+ operators
  • Useful for regulatory requirements specifying "threshold cryptography"

NIST Beacon Integration

Add NIST Randomness Beacon for applications requiring US government attestation.

optional_sources:
nist:
enabled: true
wait_for_next: true # Wait for future pulse (front-running prevention)

Properties:

  • Adds ~60 second average latency (NIST publishes every 60 seconds)
  • Provides hash chain precommitment from NIST
  • Useful for US government or regulated environments requiring NIST attestation

Hardware Entropy

Add local hardware RNG for air-gapped or high-security deployments.

optional_sources:
hardware:
enabled: true
device: "/dev/hwrng" # Or specific hardware RNG device
bytes: 32

Properties:

  • Truly random (quantum/thermal noise)
  • Not publicly verifiable (must trust operator)
  • Useful for adding defense-in-depth entropy

Becoming a Validator

Self-hosted beacons can participate in the validator network. Validators independently verify each round and submit signed attestations, creating decentralized trust.

Enable validator mode:

# In .env
VALIDATOR_MODE=true

What happens:

  1. On startup, your instance registers as a validator
  2. After each round, you submit a signed attestation
  3. Public can see your validator uptime on rng.dev/validators

Benefits:

  • Contribute to decentralized verification
  • Public recognition on validator leaderboard
  • Help ensure beacon integrity

Requirements:

  • Outbound HTTPS access to api.rng.dev
  • Stable uptime (attestations within 30s of round generation)

Your validator keypair is stored at ~/.beacon/validator.key. Back this up if you want to maintain your validator identity.


Adding Custom Sources

You can add your own entropy sources by implementing the EntropySource interface:

from app.services.fetchers.base import EntropySource

class MyCustomSource(EntropySource):
name = "mycustom"

async def fetch(self) -> str | None:
"""
Fetch entropy and return canonicalized string.
Return None if unavailable.
"""
# Your implementation here
data = await self.fetch_from_api()
return f"{data['id']}:{data['hash']}"

Register in app/services/fetchers/__init__.py:

SOURCES = [
AptosSource(),
BitcoinSource(),
CardanoSource(),
EthereumSource(),
SolanaSource(),
SuiSource(),
MyCustomSource(), # Add your source
]

Architecture

┌─────────────────────────────────────────────────────────────┐
│ Your Self-Hosted Beacon │
├─────────────────────────────────────────────────────────────┤
│ │
│ ┌──────────────┐ ┌──────────────┐ ┌──────────────┐ │
│ │ Backend │ │ PostgreSQL │ │ Redis │ │
│ │ (FastAPI) │◄─┤ │ │ │ │
│ │ Port 8000 │ │ Port 5432 │ │ Port 6379 │ │
│ └──────┬───────┘ └──────────────┘ └──────────────┘ │
│ │ │
│ ┌──────▼───────┐ │
│ │ Frontend │ (Optional) │
│ │ (Next.js) │ │
│ │ Port 3000 │ │
│ └──────────────┘ │
│ │
└─────────────────────────────────────────────────────────────┘

Production Deployment

Using Kamal

We provide Kamal configuration for bare-metal deployment:

# Configure your server in deploy/config/deploy.yml
kamal setup
kamal deploy

Manual Docker Deployment

# Build production images
docker-compose -f docker-compose.prod.yml build

# Deploy with your orchestrator of choice
docker-compose -f docker-compose.prod.yml up -d

SSL/TLS

For production, place behind a reverse proxy (nginx, Caddy, Traefik) with SSL:

server {
listen 443 ssl;
server_name beacon.yourdomain.com;

ssl_certificate /path/to/cert.pem;
ssl_certificate_key /path/to/key.pem;

location / {
proxy_pass http://localhost:8000;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
}
}

Backup & Recovery

Database Backup

# Backup
docker exec beacon-postgres pg_dump -U beacon beacon_db > backup.sql

# Restore
docker exec -i beacon-postgres psql -U beacon beacon_db < backup.sql

Important Data

The critical data to back up:

DataLocationImportance
Round historyPostgreSQL rounds tableHigh — enables verification
Source inputsPostgreSQL rounds.input_* columnsHigh — needed for re-verification
StatisticsPostgreSQL stats tablesMedium — can be recomputed
Redis cacheRedisLow — rebuilds automatically

Monitoring

Health Endpoints

# Basic health
curl http://localhost:8000/api/v1/health

# Gap detection (missing rounds)
curl http://localhost:8000/api/v1/health/gaps
  • Uptime: Monitor /api/v1/health endpoint
  • Round generation: Alert if no new round in 5+ seconds
  • Source availability: Track sources_available in responses
  • Database size: Monitor PostgreSQL disk usage

Troubleshooting

No rounds being generated

  1. Check logs: docker-compose logs backend
  2. Verify API keys are set correctly
  3. Check network connectivity to blockchain APIs
  4. Ensure at least 2 sources are reachable

High latency on round generation

  1. Check blockchain API rate limits
  2. Consider using paid RPC tiers
  3. Add fallback providers

Database growing too large

  1. Implement partitioning (see migrations/)
  2. Archive old rounds to cold storage
  3. Keep only recent data in hot storage

Differences from rng.dev

When self-hosting, note these differences:

Featurerng.devSelf-Hosted
Availability99.9% SLAYour responsibility
Validator networkPlannedCan participate
Historical dataSince genesisSince your start date
SupportEmail supportCommunity only

Contributing

Found a bug or want to add a feature?

  1. Fork the repository
  2. Create a feature branch
  3. Submit a pull request

See CONTRIBUTING.md for guidelines.


Next Steps