Skip to main content

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.

SettingValue
Imagepostgres:16-alpine
Port5432
Volumepostgres_data

Health Check: pg_isready every 5s

GraphQL API

Main API server with Prisma ORM.

SettingValue
Port3000
HealthcheckGET /health

Features:

  • GraphQL queries, mutations, subscriptions
  • JWT authentication
  • Automatic database migrations
  • Concurrent migration locking

ERC-4337 Relayer

Rust bundler for UserOperations.

SettingValue
Port3001
HealthcheckGET /health

Features:

  • UserOperation validation
  • Bundle creation and submission
  • EIP-1559 transaction support

Configuration

Environment Variables

Required

VariableDescription
POSTGRES_PASSWORDDatabase password
JWT_SECRETJWT signing secret (32+ chars)
RPC_URLEthereum RPC endpoint

Optional

VariableDefaultDescription
POSTGRES_USERzeroquantDatabase user
POSTGRES_DBzeroquantDatabase name
CHAIN_ID11155111Target chain (Sepolia)
ENTRY_POINT_ADDRESS0x5FF137D4...ERC-4337 EntryPoint
RUST_LOGinfoRelayer 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