Docker Local Environment
Knight Shield provides a docker-compose.yml at the project root that runs a complete Midnight Network stack for local development.
Services
midnight-node
image: midnightnetwork/midnight-node:v0.21.0
ports:
- "9944:9944"
The Midnight blockchain node. Exposes WebSocket RPC on port 9944 for transaction submission, block queries, and state reads.
indexer
image: midnightnetwork/indexer:v4.0.0-rc.4
ports:
- "8088:8088"
Block indexer providing a GraphQL API at http://localhost:8088/api/v1/graphql. The wallet SDK uses this for:
- Balance queries
- Transaction history
- Contract state lookups
- Sync operations
proof-server
image: midnightnetwork/proof-server:v7.0.0
ports:
- "6300:6300"
ZK proof generation server. Every Compact contract call requires a zero-knowledge proof — the proof server handles the computationally intensive proof generation.
Commands
# Start all services
docker compose up -d
# Check health
docker compose ps
# View node logs
docker compose logs -f midnight-node
# View all logs
docker compose logs -f
# Stop services
docker compose down
# Stop and remove volumes
docker compose down -v
Port Summary
| Service | Port | Protocol | Purpose |
|---|---|---|---|
| midnight-node | 9944 | WebSocket | Blockchain RPC |
| indexer | 8088 | HTTP | GraphQL API |
| proof-server | 6300 | HTTP | ZK proof generation |
| relay-server | 8443 | WebSocket | GhostCloak relay (run separately) |
Network Configuration
The standalone network in @knight-shield/core maps to these local endpoints:
const NETWORKS = {
standalone: {
node: 'http://127.0.0.1:9944',
indexer: 'http://127.0.0.1:8088/api/v1/graphql',
proofServer: 'http://127.0.0.1:6300',
},
// ...
};
Resource Requirements
| Service | CPU | RAM | Notes |
|---|---|---|---|
| midnight-node | 2 cores | 2 GB | Block production |
| indexer | 1 core | 1 GB | Depends on node being synced |
| proof-server | 4 cores | 4 GB | ZK proof generation is CPU-intensive |
The proof server is the most resource-hungry component. Proof generation times depend on circuit complexity — simple transfers take seconds, complex contract calls may take longer.
Troubleshooting
| Symptom | Cause | Solution |
|---|---|---|
| Node not producing blocks | First start initialization | Wait 30-60 seconds for genesis |
| Indexer errors on startup | Node not ready | Restart indexer after node is synced |
| Proof timeout | Insufficient CPU/RAM | Allocate more resources to Docker |
| Port conflict | Another service on same port | Change port mapping in docker-compose.yml |