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/rngdotdev/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​