Self-Hosting
OPP_NET is fully self-hostable. Run your own indexer, RPC server, and block explorer with complete sovereignty over your data.
Components
| Service | Image | Port |
|---|
| metashrew (indexer) | metashrew-opnet:latest | 8080 |
| opnet-jsonrpc (gateway) | opnet-jsonrpc:latest | 18889 |
| btcrpc-proxy | btcrpc-proxy:latest | 8332 |
| osprey (explorer backend) | osprey:latest | 18890 |
| esplora (explorer) | esplora:latest | 50010 |
Docker Compose (Quickstart)
version: '3.8'
services:
btcrpc-proxy:
image: us-east1-docker.pkg.dev/opp-net-proj/opnet/btcrpc-proxy:latest
environment:
UPSTREAM_URL: "https://mempool.opnet.org/testnet4"
RUST_LOG: info
ports:
- "8332:8332"
metashrew:
image: us-east1-docker.pkg.dev/opp-net-proj/opnet/metashrew-opnet:latest
environment:
DAEMON_RPC_ADDR: "http://btcrpc-proxy:8332"
START_BLOCK: "0"
RUST_LOG: "none,rockshrew=debug"
volumes:
- metashrew-data:/data
ports:
- "8080:8080"
depends_on:
- btcrpc-proxy
opnet-jsonrpc:
image: us-east1-docker.pkg.dev/opp-net-proj/opnet/opnet-jsonrpc:latest
environment:
SERVER_PORT: "18889"
BITCOIN_RPC_URL: "http://btcrpc-proxy:8332"
METASHREW_URL: "http://metashrew:8080"
ESPLORA_URL: "http://esplora:50010"
RUST_LOG: info
ports:
- "18889:18889"
depends_on:
- metashrew
- btcrpc-proxy
osprey:
image: us-east1-docker.pkg.dev/opp-net-proj/opnet/osprey:latest
environment:
JSONRPC_URL: "http://opnet-jsonrpc:18889"
LISTEN_ADDR: "0.0.0.0:18890"
RUST_LOG: info
volumes:
- osprey-data:/data
ports:
- "18890:18890"
depends_on:
- opnet-jsonrpc
esplora:
image: us-east1-docker.pkg.dev/opp-net-proj/opnet/esplora:latest
environment:
ELECTRS_NETWORK: testnet
ELECTRS_DAEMON_RPC_ADDR: "btcrpc-proxy:8332"
ELECTRS_HTTP_ADDR: "0.0.0.0:50010"
volumes:
- esplora-data:/data
ports:
- "50010:50010"
depends_on:
- btcrpc-proxy
volumes:
metashrew-data:
osprey-data:
esplora-data:
Kubernetes (Production)
OPP_NET uses Flux GitOps for production deployments. The full Kubernetes manifests are in the oppnet repository underk8s/.
Namespace Structure
k8s/
├── regtest-opnet/ # Regtest environment
│ ├── namespace.yaml
│ ├── bitcoind.yaml # Local bitcoind for regtest
│ ├── metashrew.yaml # Indexer (StatefulSet with PVC)
│ ├── opnet-jsonrpc.yaml
│ ├── osprey.yaml # Explorer backend (polls traces, REST API)
│ ├── esplora.yaml
│ └── openresty.yaml # Reverse proxy (LoadBalancer)
│
├── optb1-opnet/ # Testnet4 environment
│ ├── namespace.yaml
│ ├── btcrpc-proxy.yaml # Proxies to mempool.opnet.org/testnet4
│ ├── metashrew.yaml
│ ├── opnet-jsonrpc.yaml
│ ├── osprey.yaml
│ ├── alkanes-jsonrpc.yaml
│ └── esplora.yaml
│
└── base/ # Shared base manifests
Flux GitOps
# Flux watches the git repo and auto-applies changes
clusters/regtest-opnet/
├── flux-system/ # Flux bootstrap
├── regtest-opnet.yaml # Kustomization for regtest
└── optb1-opnet.yaml # Kustomization for testnet4
Building Images
metashrew-opnet
# From the oppnet repo root:
docker build -f docker/metashrew-opnet/Dockerfile \
-t metashrew-opnet:latest .
# This builds:
# 1. rockshrew-mono (metashrew host) from source
# 2. opshrew.wasm (indexer WASM module) from submodules/opshrew/
# 3. Runtime image with both binaries
opnet-jsonrpc
cd services/opnet-jsonrpc
docker build -t opnet-jsonrpc:latest .
btcrpc-proxy
# btcrpc-proxy is a simple Rust HTTP proxy
# It translates Bitcoin Core JSON-RPC to the upstream block source
# For testnet4: proxies to mempool.opnet.org/testnet4
# For regtest: connects to local bitcoind
#
# This enables OPP_NET to index the canonical OP_NET network,
# providing compatibility with legacy assets like MOTO.
Configuration
Environment Variables
| Variable | Service | Description |
|---|
DAEMON_RPC_ADDR | metashrew | Bitcoin RPC endpoint |
START_BLOCK | metashrew | Block to start indexing from |
BITCOIN_RPC_URL | opnet-jsonrpc | bitcoind/proxy URL |
METASHREW_URL | opnet-jsonrpc | metashrew view RPC URL |
ESPLORA_URL | opnet-jsonrpc | Esplora HTTP API URL |
UPSTREAM_URL | btcrpc-proxy | Upstream block source |
SERVER_PORT | opnet-jsonrpc | Listen port (default: 18888) |
JSONRPC_URL | osprey | opnet-jsonrpc URL to poll traces from |
LISTEN_ADDR | osprey | REST API listen address (default: 0.0.0.0:18890) |
Storage Requirements
- metashrew: 100GB+ (RocksDB, grows with chain)
- esplora: 50GB+ (Electrs index)
- osprey: 20GB+ (RocksDB secondary indexes, 17 column families)
- btcrpc-proxy: Stateless
- opnet-jsonrpc: Stateless
Resource Recommendations
| Service | CPU | Memory |
|---|
| metashrew | 2-4 cores | 8-16 GB |
| opnet-jsonrpc | 0.25-1 core | 256 MB - 1 GB |
| btcrpc-proxy | 0.25-1 core | 512 MB - 2 GB |
| osprey | 1-2 cores | 1-4 GB |
| esplora | 1-2 cores | 2-8 GB |