Docker Deployment
Deploy ZeroQuant services using Docker and Docker Compose.
Prerequisites
- Docker 20.10+
- Docker Compose 2.0+
- 4GB RAM minimum
- Ethereum RPC endpoint (Alchemy, Infura, etc.)
Quick Start
1. Clone the Repository
git clone https://github.com/zeroquant/zeroquant-sdk.git
cd zeroquant-sdk
2. Configure Environment
Create a .env file in the project root:
# Required
POSTGRES_PASSWORD=your_secure_password_here
JWT_SECRET=your_jwt_secret_min_32_chars
RPC_URL=https://eth-sepolia.g.alchemy.com/v2/YOUR_KEY
# Optional (with defaults)
POSTGRES_USER=zeroquant
POSTGRES_DB=zeroquant
CHAIN_ID=11155111
ENTRY_POINT_ADDRESS=0x5FF137D4b0FDCD49DcA30c7CF57E578a026d2789
RUST_LOG=info
Security
Never commit .env files to version control. Use secret management in production.
3. Start Services
# Start all services
docker compose up -d
# Check status
docker compose ps
# View logs
docker compose logs -f
Architecture
┌─────────────────────────────────────────────────────────────┐
│ Client SDKs │
│ (TypeScript / Python / Agents) │
└──────────────────────────┬──────────────────────────────────┘
│
┌─────────────────┴─────────────────┐
│ │
▼ ▼
┌─────────────────────┐ ┌─────────────────────┐
│ GraphQL API │ │ ERC-4337 Relayer │
│ Port: 3000 │ │ Port: 3001 │
│ (Node.js) │ │ (Rust) │
└─────────┬───────────┘ └─────────────────────┘
│
▼
┌─────────────────────┐
│ PostgreSQL │
│ Port: 5432 │
└─────────────────────┘
Services
PostgreSQL
Database for API data and indexing.
| Setting | Value |
|---|---|
| Image | postgres:16-alpine |
| Port | 5432 |
| Volume | postgres_data |
Health Check: pg_isready every 5s
GraphQL API
Main API server with Prisma ORM.
| Setting | Value |
|---|---|
| Port | 3000 |
| Healthcheck | GET /health |
Features:
- GraphQL queries, mutations, subscriptions
- JWT authentication
- Automatic database migrations
- Concurrent migration locking
ERC-4337 Relayer
Rust bundler for UserOperations.
| Setting | Value |
|---|---|
| Port | 3001 |
| Healthcheck | GET /health |
Features:
- UserOperation validation
- Bundle creation and submission
- EIP-1559 transaction support
Configuration
Environment Variables
Required
| Variable | Description |
|---|---|
POSTGRES_PASSWORD | Database password |
JWT_SECRET | JWT signing secret (32+ chars) |
RPC_URL | Ethereum RPC endpoint |
Optional
| Variable | Default | Description |
|---|---|---|
POSTGRES_USER | zeroquant | Database user |
POSTGRES_DB | zeroquant | Database name |
CHAIN_ID | 11155111 | Target chain (Sepolia) |
ENTRY_POINT_ADDRESS | 0x5FF137D4... | ERC-4337 EntryPoint |
RUST_LOG | info | Relayer log level |
Network Configuration
Mainnet
RPC_URL=https://eth-mainnet.g.alchemy.com/v2/YOUR_KEY
CHAIN_ID=1
ENTRY_POINT_ADDRESS=0x5FF137D4b0FDCD49DcA30c7CF57E578a026d2789
Sepolia (Testnet)
RPC_URL=https://eth-sepolia.g.alchemy.com/v2/YOUR_KEY
CHAIN_ID=11155111
ENTRY_POINT_ADDRESS=0x5FF137D4b0FDCD49DcA30c7CF57E578a026d2789
Arbitrum
RPC_URL=https://arb-mainnet.g.alchemy.com/v2/YOUR_KEY
CHAIN_ID=42161
ENTRY_POINT_ADDRESS=0x5FF137D4b0FDCD49DcA30c7CF57E578a026d2789
Operations
Starting Services
# All services
docker compose up -d
# Specific service
docker compose up -d api
# With build
docker compose up -d --build
Stopping Services
# Stop all
docker compose down
# Stop and remove volumes (data loss!)
docker compose down -v
Viewing Logs
# All services
docker compose logs -f
# Specific service
docker compose logs -f api
docker compose logs -f relayer
# Last 100 lines
docker compose logs --tail=100 api
Database Operations
# Connect to database
docker compose exec postgres psql -U zeroquant
# Run migrations manually
docker compose exec api pnpm --filter @zeroquant/api run db:migrate
# Reset database (data loss!)
docker compose exec api pnpm --filter @zeroquant/api run db:reset
Health Checks
# Check API
curl http://localhost:3000/health
# Check Relayer
curl http://localhost:3001/health
# Check all containers
docker compose ps
Production Deployment
Security Checklist
- Use strong, unique passwords
- Enable TLS/HTTPS (reverse proxy)
- Configure firewall rules
- Use secrets management
- Enable database backups
- Set resource limits
- Configure log rotation
Resource Limits
Add to docker-compose.yml:
services:
api:
deploy:
resources:
limits:
cpus: '2'
memory: 2G
reservations:
cpus: '0.5'
memory: 512M
relayer:
deploy:
resources:
limits:
cpus: '1'
memory: 1G
reservations:
cpus: '0.25'
memory: 256M
postgres:
deploy:
resources:
limits:
cpus: '2'
memory: 4G
Reverse Proxy (Nginx)
Example nginx configuration:
upstream api {
server localhost:3000;
}
upstream relayer {
server localhost:3001;
}
server {
listen 443 ssl http2;
server_name api.yourdomain.com;
ssl_certificate /etc/ssl/certs/api.crt;
ssl_certificate_key /etc/ssl/private/api.key;
location / {
proxy_pass http://api;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection 'upgrade';
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
}
}
server {
listen 443 ssl http2;
server_name relayer.yourdomain.com;
ssl_certificate /etc/ssl/certs/relayer.crt;
ssl_certificate_key /etc/ssl/private/relayer.key;
location / {
proxy_pass http://relayer;
proxy_http_version 1.1;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
}
}
Database Backups
# Backup
docker compose exec postgres pg_dump -U zeroquant zeroquant > backup.sql
# Restore
docker compose exec -T postgres psql -U zeroquant zeroquant < backup.sql
Automated Backups (cron)
# Add to crontab -e
0 */6 * * * cd /path/to/zeroquant && docker compose exec -T postgres pg_dump -U zeroquant zeroquant | gzip > /backups/zeroquant-$(date +\%Y\%m\%d-\%H\%M).sql.gz
Troubleshooting
Container Won't Start
# Check logs
docker compose logs api
# Check configuration
docker compose config
# Rebuild
docker compose build --no-cache api
Database Connection Failed
# Check postgres is healthy
docker compose ps postgres
# Check connectivity
docker compose exec api nc -zv postgres 5432
# Check credentials
docker compose exec postgres psql -U zeroquant -c "SELECT 1"
Migration Issues
# Check migration status
docker compose exec api pnpm --filter @zeroquant/api run db:status
# Reset migrations (dev only!)
docker compose exec api pnpm --filter @zeroquant/api run db:reset
Out of Memory
# Check memory usage
docker stats
# Increase Docker memory limit in Docker Desktop settings
# Or add swap space on Linux
Port Already in Use
# Find process using port
lsof -i :3000
# Kill process
kill -9 <PID>
# Or change port in docker-compose.yml
ports:
- "3100:3000" # Use 3100 instead
Development Mode
For local development with hot-reload:
# Start only postgres
docker compose up -d postgres
# Run API locally
cd packages/api
pnpm dev
# Run relayer locally
cd packages/relayer
cargo run
Next Steps
- TypeScript SDK - SDK setup
- Python SDK - Python setup
- API Reference - Full API docs
- Relayer Docs - Relayer configuration