Self-Hosting

OPP_NET is fully self-hostable. Run your own indexer, RPC server, and block explorer with complete sovereignty over your data.

Components

ServiceImagePort
metashrew (indexer)metashrew-opnet:latest8080
opnet-jsonrpc (gateway)opnet-jsonrpc:latest18889
btcrpc-proxybtcrpc-proxy:latest8332
osprey (explorer backend)osprey:latest18890
esplora (explorer)esplora:latest50010

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

VariableServiceDescription
DAEMON_RPC_ADDRmetashrewBitcoin RPC endpoint
START_BLOCKmetashrewBlock to start indexing from
BITCOIN_RPC_URLopnet-jsonrpcbitcoind/proxy URL
METASHREW_URLopnet-jsonrpcmetashrew view RPC URL
ESPLORA_URLopnet-jsonrpcEsplora HTTP API URL
UPSTREAM_URLbtcrpc-proxyUpstream block source
SERVER_PORTopnet-jsonrpcListen port (default: 18888)
JSONRPC_URLospreyopnet-jsonrpc URL to poll traces from
LISTEN_ADDRospreyREST API listen address (default: 0.0.0.0:18890)

Storage Requirements

Resource Recommendations

ServiceCPUMemory
metashrew2-4 cores8-16 GB
opnet-jsonrpc0.25-1 core256 MB - 1 GB
btcrpc-proxy0.25-1 core512 MB - 2 GB
osprey1-2 cores1-4 GB
esplora1-2 cores2-8 GB