Take a self-hosted instance from localhost to production.
A production explorer needs TLS, a stable database, and enough headroom for indexing under load. This guide covers the essentials.
Architecture for production
┌─────────────┐ HTTPS ──────▶│ Reverse proxy│ (nginx / Caddy / Traefik) └──────┬──────┘ ┌────────────┼────────────┐ ▼ ▼ ▼ Frontend API/backend (static) │ ┌────┴────┐ ▼ ▼ PostgreSQL Chain RPC node- Reverse proxy terminates TLS and routes
/apito the backend and everything else to the frontend. - PostgreSQL runs with persistent storage, regular backups, and preferably on separate disks from the OS.
- RPC node runs on dedicated hardware for busy chains — the indexer’s trace calls are heavy.
TLS and reverse proxy
Example nginx server block:
server { listen 443 ssl; server_name explorer.example.com;
ssl_certificate /etc/letsencrypt/live/explorer.example.com/fullchain.pem; ssl_certificate_key /etc/letsencrypt/live/explorer.example.com/privkey.pem;
location /api/ { proxy_pass http://127.0.0.1:4000; proxy_set_header Host $host; proxy_set_header X-Real-IP $remote_addr; proxy_read_timeout 60s; }
location / { proxy_pass http://127.0.0.1:3000; proxy_set_header Host $host; }}Caddy is a zero-config alternative:
explorer.example.com
reverse_proxy /api/* 127.0.0.1:4000reverse_proxy 127.0.0.1:3000Update the frontend env to the public hostname (NEXT_PUBLIC_API_HOST=explorer.example.com) and recreate the frontend container.
Database
- Persistence: mount a volume for PostgreSQL data (
-v pgdata:/var/lib/postgresql/data). Never run production without it. - Sizing: a full mainnet index with internal transactions can reach hundreds of GB. Plan for growth and use fast NVMe storage.
- Backups: schedule
pg_dumpor filesystem snapshots; test restores. See Maintenance & Operations. - Connection limits: the indexer holds many connections; raise
max_connections(e.g. 200) on busy instances.
Scaling
| Bottleneck | Mitigation |
|---|---|
| API request volume | Run multiple backend replicas behind the proxy (stateless reads) |
| Indexing lag | Faster disks, archive node on the same LAN, tune indexer memory |
| Frontend load | Static assets through a CDN; frontend replicas behind the proxy |
| Database I/O | Dedicated NVMe, tuned shared_buffers (~25% of RAM) |
The indexer itself is a singleton — do not run two indexer processes against the same database.
Resource guidance
| Chain size | vCPU | RAM | Storage |
|---|---|---|---|
| Devnet / small testnet | 4 | 8 GB | 200 GB |
| Medium network | 8 | 16 GB | 1 TB |
| Busy mainnet (full traces) | 16 | 32 GB | 2+ TB |
Security checklist
- TLS everywhere; redirect HTTP to HTTPS
- Database not exposed to the public internet
- Strong
DATABASE_URLcredentials - Rate limits configured (
API_RATE_LIMIT) - OS and container images patched; automatic security updates on
- Backups scheduled and restore-tested
Multiple chains
Run one compose stack per chain, each with its own database volume, ports, and hostname (e.g. explorer-xdc.example.com, explorer-testnet.example.com). A single reverse proxy can front all of them.
Next steps
- Maintenance & Operations — upgrades, reindexing, backups
- Monitoring — health checks and metrics
- Operations Command Reference