Docker
Run Sieve with Docker Compose or build your own image.
Docker Compose
sieve init --docker docker compose up -d
Creates sieve.toml, .env, abis/, and docker-compose.yml. Starts PostgreSQL and Sieve with GraphQL API on port 4000. Credentials come from .env. Edit sieve.toml for your contracts, or use the default USDC Transfer config.
The generated compose file exposes the discv5 UDP port (30304) that OP Mainnet, Unichain, and World Chain need for peer discovery.
Manual build
docker build -t sieve . docker run \ -v ./sieve.toml:/app/sieve.toml:ro \ -v ./abis:/app/abis:ro \ -p 4000:4000 -p 30303:30303 -p 30303:30303/udp \ -p 30304:30304/udp \ sieve --database-url postgres://... --api-port 4000
Config and ABIs are mounted as volumes, not baked into the image. One image works for dev, staging, and production.
Networking
Port 30303 (TCP + UDP) carries RLPx and discovery and must be reachable from the internet. If you're behind NAT or a firewall, make sure it is forwarded.
OP Mainnet, Unichain, and World Chain also use UDP 30304 for discv5. Base runs its basev0 discovery on 30303/UDP and needs nothing extra. Expose the ports your chain needs.
Use sieve peers to test connectivity before running the full indexer. It reports peer count and chain head every 5 seconds, useful for diagnosing Docker/NAT issues.
Exposing the API
The GraphQL server has open CORS and no built-in auth. Put it behind a reverse proxy with TLS, access control, and rate limiting before exposing it to the internet.
Multiple instances
One container per instance is the simplest way to run several chains on one host, since each gets its own network namespace. Each instance still needs its own database and API port, and a worker cap so they don't oversubscribe the cores. See Multiple Instances.